/* ==========================================================================
   SITE — components, behaviours and per-breakpoint geometry
   All numbers are design-grid units (see engine.css).
   ========================================================================== */

/* ==========================================================================
   1. LINKS — the universal hover "marker"
   A cream block sweeps in from the left behind the text on hover.
   ========================================================================== */

.atom a {
  color: inherit;
  text-decoration: none;
  position: relative;
  display: inline;
  z-index: 1;
}

.atom a::before {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  background-color: var(--marker);
  z-index: -1;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-marker);
}

.atom:not(.no-marker) a:hover::before { transform: scaleX(1); }

/* Opt out on any link that should not get the marker */
.no-marker a::before,
.no-marker a:hover::before { display: none; }

/* ==========================================================================
   2. HEADER
   Fixed, transparent over the dark hero; turns solid the moment the page
   scrolls past 50px, with the menu type flipping cream -> ink.
   ========================================================================== */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 99999;
  background-color: transparent;
  transition: background-color var(--t-header), box-shadow var(--t-header);
}

.site-header.scrolled {
  background-color: var(--bg-header-solid);
  box-shadow: var(--header-shadow);
}

.menu-links a {
  color: var(--text-on-dark);
  transition: color var(--t-link);
}

.site-header.scrolled .menu-links a { color: var(--text-on-light); }

/* Menu links sit on the cream marker on hover, so they invert to ink */
.white-link-fix a:hover { color: var(--text-on-light); }

/* Live CET clock. The source uses flat white/black here rather than the
   paper/ink tokens — kept as-is. */
.clock {
  font-family: var(--font-sans);
  font-weight: var(--fw);
  font-size: calc(11 * var(--u));
  line-height: 1.55;
  color: #ffffff;
  text-align: right;
  white-space: nowrap;
  letter-spacing: 0.02em;
  transition: color var(--t-link);
}

.site-header.scrolled .clock { color: #000000; }

/* Brand mark carries a permanent cream highlight */
.brand-mark { background-color: var(--c-cream); }

/* ==========================================================================
   3. SECTION SURFACES
   ========================================================================== */

.zb--hero     .zb__artboard { background-color: var(--bg-hero);          color: var(--text-on-dark); }
.zb--light    .zb__artboard { background-color: var(--bg-section-light); color: var(--text-on-light); }
.zb--footer   .zb__artboard { background-color: var(--bg-footer);        color: var(--text-on-light); }

/* Viewport-locked blocks: at least --zb-vh tall, and growing with the grid on
   wide screens — rendered height = max(base * scale, --zb-vh). */
.zb--vh .zb__artboard { height: max(calc(var(--zb-h) * var(--u)), var(--zb-vh, 100vh)); }

.zb--hero { --zb-vh: 100vh; }

/* Inner pages open on a light header rather than fading in over a dark hero */
.site-header--solid                     { background-color: var(--bg-header-solid); }
.site-header--solid .menu-links a       { color: var(--text-on-light); }
.site-header--solid .clock              { color: #000000; }

/* ==========================================================================
   4. GEOMETRY — 1200 grid (viewport >= 1200px)
   ========================================================================== */

/* ---- Header -------------------------------------------------------------- */
.zb--header             { --zb-h: 36; }
.el-brand               { --t: 10;  --l: 20;  --fs: 11; --lh: 1.55; color: var(--text-on-light); }
.el-nav-work            { --t: 10;  --l: 407; --fs: 11; --lh: 1.55; }
.el-nav-services        { --t: 10;  --l: 439; --fs: 11; --lh: 1.55; }
.el-nav-contact         { --t: 10;  --l: 469; --fs: 11; --lh: 1.55; }
.el-clock               { --t: 12;  --l: 997; --w: calc(183 * var(--u)); --h: calc(17 * var(--u)); }

/* ---- Hero ---------------------------------------------------------------- */
.zb--hero               { --zb-h: 700; }
.el-hero-art-a          { --t: -820; --l: 0;     --w: calc(1200 * var(--u)); --h: calc(750 * var(--u)); }
.el-hero-art-b          { --t: 0;    --l: -1345; --w: calc(600  * var(--u)); --h: calc(928 * var(--u)); }
.el-hero-title          { --b: 110;  --l: 408;   --w: calc(562  * var(--u)); --fs: 30; --lh: 1.1; }

/* ---- About --------------------------------------------------------------- */
.zb--about              { --zb-h: 280; }
.el-about-label         { --t: 105; --l: 20;  --fs: 11; --lh: 1.55; }
.el-about-text          { --t: 100; --l: 410; --w: calc(566 * var(--u)); --fs: 20; --lh: 1.15; }

/* ---- Contacts ------------------------------------------------------------ */
.zb--contacts           { --zb-h: 188; }
.el-contacts-label      { --t: 45; --l: 20;  --fs: 11; --lh: 1.55; }
.el-contact-email       { --t: 40; --l: 410; --fs: 20; --lh: 1.15; }

/* ---- Footer -------------------------------------------------------------- */
.zb--footer             { --zb-h: 38; }
.el-footer-brand        { --t: 11; --l: 20;   --fs: 11; --lh: 1.55; }
.el-footer-note         { --b: 12; --l: 407;  --w: calc(240 * var(--u)); --h: calc(14 * var(--u)); --fs: 11; --lh: 1.3; }
.el-footer-policy       { --b: 12; --l: 1051; --fs: 11; --lh: 1.3; }
.el-footer-impressum    { --b: 12; --l: 1127; --fs: 11; --lh: 1.3; }
/* Parked below the footer edge in the source, so clipped out of view.
   Move --b to a positive value to bring it in. */
.el-footer-email        { --b: -79; --l: 413; --fs: 11; --lh: 1.3; }

/* ==========================================================================
   5. GEOMETRY — 960 grid (viewport 960–1199px)
   ========================================================================== */
@media screen and (max-width: 1199px) {

  .el-brand             { --l: 10; }
  .el-nav-work          { --l: 327; }
  .el-nav-services      { --l: 359; }
  .el-nav-contact       { --l: 389; }
  .el-clock             { --t: 11; --l: 767; }

  .zb--hero             { --zb-h: 600; }
  .el-hero-art-a        { --t: -670; --l: -5; --w: calc(970 * var(--u)); --h: calc(606 * var(--u)); }
  .el-hero-title        { --b: 120; --l: 325; --w: calc(465 * var(--u)); --fs: 30; }

  .zb--about            { --zb-h: 260; }
  .el-about-label       { --t: 86; --l: 10; }
  .el-about-text        { --t: 80; --l: 325; --w: calc(585 * var(--u)); }

  .zb--contacts         { --zb-h: 167; }
  .el-contacts-label    { --t: 46; --l: 10; }
  .el-contact-email     { --t: 40; --l: 325; }

  .zb--footer           { --zb-h: 34; }
  .el-footer-brand      { --l: 10; }
  .el-footer-note       { --b: 10; --l: 330; }
  .el-footer-policy     { --b: 10; --l: 811; }
  .el-footer-impressum  { --b: 10; --l: 887; }
  .el-footer-email      { --b: -117; --l: 325; }
}

/* ==========================================================================
   6. GEOMETRY — 640 grid (viewport 640–959px)
   ========================================================================== */
@media screen and (max-width: 959px) {

  .el-brand             { --t: 10; --l: 10; }
  .el-nav-work          { --l: 166; }
  .el-nav-services      { --l: 196; }
  .el-nav-contact       { --l: 224; }
  .menu-links           { text-align: right; }
  .el-clock             { --t: 12; --l: 447; }

  .zb--hero             { --zb-h: 400; }
  .el-hero-art-a        { --t: -422; --l: 0; --w: calc(640 * var(--u)); --h: calc(400 * var(--u)); }
  .el-hero-title        { --b: 80; --l: 10; --w: calc(308 * var(--u)); --fs: 20; --lh: 1.2; }

  .zb--about            { --zb-h: 238; }
  .el-about-label       { --t: 65; --l: 10; }
  .el-about-text        { --t: 61; --l: 166; --w: calc(440 * var(--u)); --fs: 18; }

  .zb--contacts         { --zb-h: 135; }
  .el-contacts-label    { --t: 34; --l: 10; }
  .el-contact-email     { --t: 30; --l: 166; --fs: 18; }

  .zb--footer           { --zb-h: 35; }
  .el-footer-brand      { --t: 10; --l: 10; }
  .el-footer-note       { --b: 10; --l: 166; --w: calc(189 * var(--u)); --h: auto; }
  .el-footer-policy     { --b: 10; --l: 495; }
  .el-footer-impressum  { --b: 10; --l: 567; }
  .el-footer-email      { --b: -77; --l: 163; }
}

/* ==========================================================================
   7. GEOMETRY — 320 grid (viewport < 640px)
   Note: several footer elements switch from bottom- to top-anchored here,
   and the brand + clock are pushed outside the grid (clipped) in the source.
   ========================================================================== */
@media screen and (max-width: 639px) {

  .zb--header           { --zb-h: 34; }
  .el-brand             { --t: 10; --l: 10;  --fs: 10; }
  .el-nav-work          { --t: 10; --l: 200; --fs: 10; }
  .el-nav-services      { --t: 10; --l: 230; --fs: 10; }
  .el-nav-contact       { --t: 10; --l: 258; --fs: 10; }
  .el-clock             { --t: 12; --l: 447; }

  .zb--hero             { --zb-h: 600; }
  .el-hero-art-a        { --t: 0;    --l: -729; --w: calc(640 * var(--u)); --h: calc(400 * var(--u)); }
  .el-hero-art-b        { --t: -550; --l: -1;   --w: calc(322 * var(--u)); --h: calc(498 * var(--u)); }
  .el-hero-title        { --b: 54; --l: 10; --w: calc(298 * var(--u)); --fs: 20; }

  .zb--about            { --zb-h: 301; }
  .el-about-label       { --t: 62; --l: 10; --fs: 10; }
  .el-about-text        { --t: 61; --l: 87; --w: calc(217 * var(--u)); --fs: 14; }

  .zb--contacts         { --zb-h: 112; }
  .el-contacts-label    { --t: 31; --l: 10; --fs: 10; }
  .el-contact-email     { --t: 30; --l: 87; --fs: 14; }

  .zb--footer           { --zb-h: 45; }
  .el-footer-brand      { --t: 10; --l: -80; --fs: 10; }

  /* top-anchored from here down */
  .el-footer-note       { --t: 8;   --l: 10;  --w: calc(102 * var(--u)); --h: calc(28 * var(--u));
                          --fs: 10; --lh: 1.44; top: calc(var(--t) * var(--u)); bottom: auto; }
  .el-footer-policy     { --t: 10;  --l: 250; --fs: 10; top: calc(var(--t) * var(--u)); bottom: auto; }
  .el-footer-impressum  { --t: 23;  --l: 262; --fs: 10; top: calc(var(--t) * var(--u)); bottom: auto; }
  .el-footer-email      { --t: 130; --l: 225; --fs: 10; top: calc(var(--t) * var(--u)); bottom: auto; }
}

/* ==========================================================================
   8. PAGE: WORK
   Own full-height block on a cream ground, with the statement bottom-left.
   ========================================================================== */

.zb--work              { --zb-h: 650; --zb-vh: 85vh; }
.zb--work .zb__artboard { background-color: var(--c-cream); color: var(--text-on-light); }
.el-work-title         { --b: 131; --l: 408; --w: calc(716 * var(--u)); --fs: 30; --lh: 1.1; }

@media screen and (max-width: 1199px) {
  .zb--work            { --zb-h: 600; }
  .el-work-title       { --b: 101; --l: 325; --w: calc(562 * var(--u)); --fs: 30; }
}

@media screen and (max-width: 959px) {
  .zb--work            { --zb-h: 400; }
  /* top-anchored at this breakpoint in the source */
  .el-work-title       { --t: 224; --l: 165; --w: calc(350 * var(--u)); --fs: 20; --lh: 1.2;
                         top: calc(var(--t) * var(--u)); bottom: auto; }
}

@media screen and (max-width: 639px) {
  .zb--work            { --zb-h: 500; --zb-vh: 90vh; }
  .el-work-title       { --b: 110; --l: 10; --w: calc(298 * var(--u)); --h: calc(72 * var(--u));
                         --fs: 20; top: auto; bottom: calc(var(--b) * var(--u)); }
}

/* ==========================================================================
   9. PAGE SHELLS — services / contact / impressum / policy
   Same chrome and grid as everything else; drop your blocks inside.
   ========================================================================== */

.zb--page              { --zb-h: 600; }
.zb--page .zb__artboard { background-color: var(--bg-section-light); color: var(--text-on-light); }
.el-page-label         { --t: 105; --l: 20;  --fs: 11; --lh: 1.55; }
.el-page-title         { --t: 100; --l: 408; --w: calc(716 * var(--u)); --fs: 30; --lh: 1.1; }

@media screen and (max-width: 1199px) {
  .el-page-label       { --t: 86; --l: 10; }
  .el-page-title       { --t: 80; --l: 325; --w: calc(562 * var(--u)); }
}

@media screen and (max-width: 959px) {
  .zb--page            { --zb-h: 460; }
  .el-page-label       { --t: 65; --l: 10; }
  .el-page-title       { --t: 61; --l: 166; --w: calc(440 * var(--u)); --fs: 20; --lh: 1.2; }
}

@media screen and (max-width: 639px) {
  .zb--page            { --zb-h: 420; }
  .el-page-label       { --t: 62; --l: 10; --fs: 10; }
  .el-page-title       { --t: 61; --l: 87; --w: calc(217 * var(--u)); --fs: 20; }
}

/* ==========================================================================
   10. FLOW BLOCKS
   The reference layout is entirely fixed-height. Listing pages (work index,
   CV) have to grow with their content, so these artboards are auto-height
   and hold one in-flow column indented onto the same grid column the fixed
   blocks use. Everything else — type scale, colour, marker — is unchanged.
   ========================================================================== */

.zb--flow .zb__artboard {
  height: auto;
  min-height: calc(var(--zb-h, 0) * var(--u));
  overflow: visible;
  background-color: var(--bg-section-light);
  color: var(--text-on-light);
}

.zb__el--flow {
  position: relative;
  display: block;
  top: auto;
  left: auto;
  width: auto;
  margin-left: calc(var(--l, 0) * var(--u));
  margin-right: calc(20 * var(--u));
  max-width: var(--w, none);
  padding-top: calc(var(--t, 0) * var(--u));
  padding-bottom: calc(var(--pb, 60) * var(--u));
}

.zb__el--flow > .atom { display: block; }

/* ---- Listing rows ------------------------------------------------------- */

.list { list-style: none; margin: 0; padding: 0; }

.list li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: calc(24 * var(--u));
  padding: calc(9 * var(--u)) 0;
  border-top: 1px solid rgba(26, 26, 26, 0.18);
}

.list li:last-child { border-bottom: 1px solid rgba(26, 26, 26, 0.18); }

.list .title { font-size: calc(20 * var(--u)); line-height: 1.15; }
.list .meta  { font-size: calc(11 * var(--u)); line-height: 1.55; white-space: nowrap; opacity: 0.65; }

@media screen and (max-width: 959px) { .list .title { font-size: calc(18 * var(--u)); } }
@media screen and (max-width: 639px) { .list .title { font-size: calc(14 * var(--u)); } }

/* ---- CV blocks ---------------------------------------------------------- */

.cv { margin: 0 0 calc(26 * var(--u)) 0; }

.cv h3 {
  margin: 0 0 calc(6 * var(--u)) 0;
  font-size: calc(11 * var(--u));
  line-height: 1.55;
  font-weight: var(--fw);
  opacity: 0.65;
}

.cv dl { margin: 0; }

.cv .row {
  display: flex;
  gap: calc(20 * var(--u));
  padding: calc(3 * var(--u)) 0;
  font-size: calc(20 * var(--u));
  line-height: 1.15;
}

.cv .row .when { flex: 0 0 calc(150 * var(--u)); opacity: 0.65; font-size: calc(11 * var(--u)); line-height: 1.9; }

@media screen and (max-width: 959px) {
  .cv .row { font-size: calc(18 * var(--u)); }
  .cv .row .when { flex-basis: calc(120 * var(--u)); }
}
@media screen and (max-width: 639px) {
  .cv .row { font-size: calc(14 * var(--u)); display: block; }
  .cv .row .when { margin-bottom: calc(2 * var(--u)); }
}

/* ---- Flow-block geometry ------------------------------------------------ */

.zb--flow                { --zb-h: 400; }
.el-flow-label           { --t: 100; --l: 20; --fs: 11; --lh: 1.55; }
.el-flow-body            { --t: 100; --l: 407; --w: calc(716 * var(--u)); --fs: 20; --lh: 1.15; --pb: 80; }

@media screen and (max-width: 1199px) {
  .el-flow-label         { --t: 80; --l: 10; }
  .el-flow-body          { --t: 80; --l: 325; --w: calc(585 * var(--u)); }
}

@media screen and (max-width: 959px) {
  .el-flow-label         { --t: 61; --l: 10; }
  .el-flow-body          { --t: 61; --l: 166; --w: calc(440 * var(--u)); --fs: 18; --pb: 60; }
}

@media screen and (max-width: 639px) {
  .el-flow-label         { --t: 34; --l: 10; }
  .el-flow-body          { --t: 56; --l: 10; --w: none; --fs: 14; --pb: 50; }
}

/* ---- Project pages ------------------------------------------------------ */

.project-title {
  margin: 0 0 calc(10 * var(--u)) 0;
  font-size: calc(30 * var(--u));
  line-height: 1.1;
  font-weight: var(--fw);
}

.project-meta {
  margin: 0 0 calc(24 * var(--u)) 0;
  font-size: calc(11 * var(--u));
  line-height: 1.55;
  opacity: 0.65;
}

.project-body {
  margin: 0 0 calc(16 * var(--u)) 0;
  font-size: calc(20 * var(--u));
  line-height: 1.15;
}

/* Media frame. Every image and video sits in the same fixed box and is
   contained inside it, so nothing is cropped, everything reads at a
   comparable size, and an autoplaying slideshow never shifts the page as it
   advances. The frame is sized to the median aspect of the library (4:5) and
   is transparent, so only the artwork itself is ever visible — a wide or very
   tall piece simply sits smaller inside it, with no visible box. */

.figures,
.slideshow { max-width: calc(var(--media-w, 400) * var(--u)); }

.figures,
.slideshow { margin-top: calc(14 * var(--u)); }

.figures figure { margin: 0; }

.figures figure,
.slideshow__stage {
  position: relative;
  aspect-ratio: var(--media-ar, 4 / 5);
  overflow: hidden;
}

.figures img,
.figures video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.project-back {
  margin: calc(40 * var(--u)) 0 0 0;
  font-size: calc(11 * var(--u));
  line-height: 1.55;
}

@media screen and (max-width: 959px) {
  .project-title { font-size: calc(20 * var(--u)); line-height: 1.2; }
  .project-body  { font-size: calc(18 * var(--u)); }
}

@media screen and (max-width: 639px) {
  .project-body  { font-size: calc(14 * var(--u)); }
  .project-meta,
  .project-back  { font-size: calc(10 * var(--u)); }
}

/* ---- Slideshow ---------------------------------------------------------- */
/* Used on any project with more than one file. Single-file projects keep the
   plain .figures block. */



.slideshow__stage {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.slide {
  position: absolute;
  inset: 0;
  display: none;
  margin: 0;
}

.slide.is-active { display: block; }

.slide img,
.slide video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.slideshow__bar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: calc(20 * var(--u));
  margin-top: calc(10 * var(--u));
  padding: calc(9 * var(--u)) 0;
  border-top: 1px solid rgba(26, 26, 26, 0.18);
  font-size: calc(11 * var(--u));
  line-height: 1.55;
}

.slideshow__nav { display: flex; gap: calc(16 * var(--u)); }

.slideshow__btn {
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font-family: var(--font-sans);
  font-weight: var(--fw);
  font-size: inherit;
  line-height: inherit;
  color: inherit;
  cursor: pointer;
  transition: opacity var(--t-link);
}

.slideshow__btn:hover { opacity: 0.5; }
.slideshow__btn:focus-visible { outline: 1px solid var(--c-ink); outline-offset: 3px; }

.slideshow__count {
  opacity: 0.65;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

@media screen and (max-width: 639px) {
  .slideshow__bar { font-size: calc(10 * var(--u)); }
}

/* Media frame. --media-w is the frame width in grid units; --media-ar is its
   shape. 4/5 matches the median aspect of the library, so the portrait work
   fills the frame exactly; wide and very tall pieces letterbox. Try 1/1 for a
   more even split between the two. */
.figures, .slideshow { --media-w: 400; --media-ar: 4 / 5; }
@media screen and (max-width: 1199px) { .figures, .slideshow { --media-w: 360; } }
@media screen and (max-width:  959px) { .figures, .slideshow { --media-w: 340; } }
@media screen and (max-width:  639px) { .figures, .slideshow { --media-w: 290; } }

/* ---- Per-project frame shape ------------------------------------------- */
/* Each project's frame is cut to its own work, so a slideshow never shifts
   as it advances and consistent projects show no empty space at all. The
   ratio is the geometric mean of the project's widest and tallest piece,
   which minimises the worst-case letterboxing on the mixed ones. */

.p-a-gesture          { --media-ar: 3 / 2; }   /* n=7  1.50–1.50  worst empty 0% */
.p-balkan-story-map-  { --media-ar: 25 / 21; }   /* n=9  0.80–1.78  worst empty 33% */
.p-fringe             { --media-ar: 25 / 23; }   /* n=4  0.67–1.78  worst empty 39% */
.p-jake               { --media-ar: 39 / 22; }   /* n=3  1.77–1.78  worst empty 0% */
.p-loom               { --media-ar: 2 / 3; }   /* n=3  0.67–0.67  worst empty 0% */
.p-mickoje            { --media-ar: 4 / 5; }   /* n=6  0.80–0.80  worst empty 0% */
.p-parku              { --media-ar: 4 / 5; }   /* n=6  0.80–0.80  worst empty 0% */
.p-pnh                { --media-ar: 3 / 4; }   /* n=2  0.71–0.80  worst empty 6% */
.p-rtk                { --media-ar: 27 / 17; }   /* n=6  1.42–1.78  worst empty 11% */
.p-uiux-bashke        { --media-ar: 11 / 23; }   /* n=3  0.49–0.49  worst empty 0% */
.p-uiux-forme         { --media-ar: 11 / 23; }   /* n=3  0.49–0.49  worst empty 0% */
.p-uiux-koha-app      { --media-ar: 11 / 23; }   /* n=3  0.49–0.49  worst empty 0% */
.p-une-arrita         { --media-ar: 22 / 19; }   /* n=7  0.75–1.79  worst empty 35% */
.p-woooman            { --media-ar: 27 / 19; }   /* n=1  1.42–1.42  worst empty 0% */
