/* ══════════════════════════════════════════════════════════════════════
   LockerHub Saranda
   Direction: vernacular / subject-native — the system is taken from the
   port's own artefacts (departure board, chart, wayfinding signage).

   The page is A DAY, not a night. Saranda's defining physical fact is
   glare: a limestone town in hard Ionian light, where the man-made
   objects — the board, the signage, the steel doors — read as dark
   instruments INSIDE that light. Deep bands are therefore not the field;
   they are reserved for the two moments that are genuinely about being
   stuck (the seven-hour gap, and the chart) and for dusk in the footer.

   COLOUR IS BAND-SCOPED. Every surface declares .band--sun or .band--deep,
   which swaps the whole role-token set in one rule. Nothing below the
   token block may reference a raw colour — that is what made the first
   build impossible to relight.

   Anchor hue sampled from the real sea plate: #46C3CA deep shallow,
   #7ABBAF mid, #B4C9BD sand-lit → hue ≈205. Neutrals carry a trace of it.
   Contrast verified numerically, not by eye (see §tokens).
   ══════════════════════════════════════════════════════════════════════ */

:root{
  /* ── raw palette ─────────────────────────────────────────────────────
     Named by material, referenced only by the band scopes below. */
  --sun-bg:#EEF2F1;        /* cool limestone — deliberately NOT cream    */
  --sun-surface:#F8FAFA;
  --sun-surface-2:#E3EAE9;
  --sun-ink:#0A1F26;
  --sun-ink-2:#3F5A64;
  --sun-ink-3:#4F656E;     /* the floor. Must clear 4.5 on the DARKEST light
                              surface, not just on --bg: 5.44 on sun-bg,
                              5.86 on surface, 5.03 on surface-2. The earlier
                              #586E77 passed on --bg at 4.76 and failed on
                              surface-2 at 4.40, which is where the size cards
                              and the fact strip actually sit.              */
  --sun-sea:#0E6C7A;       /* accent TEXT on light: 5.40:1               */
  --sun-amber-ink:#8A5205; /* burnt signage amber. Same lesson as ink-3: it
                              must clear 4.5 on the amber-TINTED surfaces it
                              lands on, not only on --bg. The old #9A5B06
                              was 4.80 on bg but 4.30 over the picked-rate
                              row's 18% amber wash. This is 5.06 at worst. */
  --sun-edge:#6E868F;      /* boundaries that ARE the control: 3.40 on bg,
                              3.66 on surface, 3.15 on surface-2. --line is
                              for dividers and is deliberately far weaker. */
  --amber-hi:#FFC163;      /* amber, hover                               */

  --deep-bg:#0B2027;
  --deep-surface:#102B35;
  --deep-surface-2:#163945;
  --deep-ink:#EDF1F0;
  --deep-ink-2:#9BB0B8;
  --deep-ink-3:#7B929B;
  --deep-sea:#46C3CA;      /* the sampled shallow-water colour           */

  --amber:#F0A63C;         /* ALWAYS a fill on light bands, never text   */
  --on-amber:#0A1F26;      /* 8.27:1 on amber                           */

  --f-disp:'Bricolage Grotesque',ui-sans-serif,system-ui,sans-serif;
  --f-body:'Commissioner',ui-sans-serif,system-ui,sans-serif;
  --f-mono:'Geist Mono',ui-monospace,'SFMono-Regular',monospace;

  /* --s0 is the only addition to the spacing scale: a 2px optical inset for
     chip padding and hairline offsets, which previously bypassed the scale as
     2px/3px/5px literals. --s10/--s11 deleted: zero references in the file. */
  --s0:2px;
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px;
  --s6:32px; --s7:48px; --s8:64px; --s9:96px;

  --wrap:1240px;
  --pad:clamp(20px,5vw,56px);
  --sec:clamp(72px,10vw,152px);
  --sec-out:calc(var(--sec) / 3);   /* a section's trailing air — see §rhythm */

  /* ── type scale ──────────────────────────────────────────────────────
     Five static steps and eleven fluid ones govern EVERY font-size below.
     Nothing outside this block may declare a raw px font-size.
     Static ratios: 11 → 12.5 (1.136) → 13.5 (1.08) → 15.5 (1.15) → 17.5 (1.13).
     The tight ui→data step separates two families, not two sizes: --fs-ui is
     uppercase mono chrome, --fs-data is sentence-case data and second-rank
     prose. 11px is the FLOOR and it is measured on RENDERED px — SVG text
     inherits its viewBox scale, so a declared 7px rose label renders at
     3.85px. See the SVG type floor block near the responsive rules.       */
  --fs-label :11px;
  --fs-ui    :12.5px;
  --fs-data  :13.5px;
  --fs-prose :15.5px;
  --fs-strong:17.5px;

  --fs-base  :clamp(16px,.5vw + 15px,17.5px);
  --fs-lede  :clamp(16.5px,1.15vw,19px);
  --fs-flap  :clamp(14px,1.32vw,17px);    /* floor 14: flap-seam legibility   */
  --fs-d6    :clamp(17px,1.5vw,21px);
  --fs-d5    :clamp(21px,1.9vw,26px);
  --fs-d4    :clamp(24px,2.7vw,36px);
  --fs-d3    :clamp(28px,2.7vw,38px);
  --fs-d2    :clamp(30px,3.55vw,42px);
  --fs-d1    :clamp(33px,3.9vw,50px);     /* hero h1 — the 50px cap fits the
                                             plate in all four languages     */
  --fs-num-lg:clamp(44px,5.5vw,68px);
  --fs-num-xl:clamp(52px,7vw,86px);

  /* ── prose measures — two values, nothing else ─────────────────────── */
  --measure  :46ch;   /* a full reading column                            */
  --measure-n:33ch;   /* a column that sits beside something              */

  --ease:cubic-bezier(.16,1,.3,1);
  --ease-in:cubic-bezier(.7,0,.84,0);
}

/* ── Greek faces ───────────────────────────────────────────────────────
   Bricolage ships no Greek cut (latin + latin-ext only), so under el the
   display face is Commissioner — already self-hosted as the body face, with
   first-class Greek (drawn by a Greek type designer), costing zero new bytes.
   Geist Mono has no Greek either; the mono stack falls through to system
   monos that DO carry Greek (Consolas, Menlo, DejaVu, Roboto Mono) — digits
   and Latin stay in Geist, only Greek words fall through. Bricolage's
   -.028em heading tracking is too tight for Commissioner's Greek lowercase;
   relaxed below. */
html:lang(el){
  --f-disp:'Commissioner',ui-sans-serif,system-ui,sans-serif;
  --f-mono:'Geist Mono',Consolas,Menlo,'DejaVu Sans Mono','Roboto Mono',ui-monospace,monospace;
}
html:lang(el) h1,html:lang(el) h2,html:lang(el) h3,html:lang(el) h4{letter-spacing:-.012em}

/* ── band scopes ───────────────────────────────────────────────────────
   One rule per band swaps background AND every ink together, so a dark
   section can never inherit light-band text. Sun is the page default. */
:root,
.band--sun{
  --bg:var(--sun-bg);
  --surface:var(--sun-surface);
  --surface-2:var(--sun-surface-2);
  --ink:var(--sun-ink);
  --ink-2:var(--sun-ink-2);
  --ink-3:var(--sun-ink-3);
  --sea:var(--sun-sea);
  --accent-ink:var(--sun-amber-ink);
  --edge:var(--sun-edge);
  --line:rgba(10,31,38,.17);
  --line-2:rgba(10,31,38,.085);
  --line-data:rgba(10,31,38,.14);
  --scrim:rgba(238,242,241,.86);
}
.band--deep{
  --bg:var(--deep-bg);
  --surface:var(--deep-surface);
  --surface-2:var(--deep-surface-2);
  --ink:var(--deep-ink);
  --ink-2:var(--deep-ink-2);
  --ink-3:var(--deep-ink-3);
  --sea:var(--deep-sea);
  --accent-ink:var(--amber);
  --edge:#5E7681;          /* 3.51 on --deep-bg */
  --line:rgba(237,241,240,.14);
  --line-2:rgba(237,241,240,.075);
  --line-data:rgba(237,241,240,.11);
  --scrim:rgba(11,32,39,.86);
}
.band--sun,.band--deep{background:var(--bg);color:var(--ink)}

/* material — limestone grain behind the flat sun bands. Grayscaled so the
   ochre master can't warm the deliberately-cool --bg; z-index:-1 inside an
   isolated context keeps it under every card and ink. */
@media (min-width:1081px){
  .how,.sizes,.go,.price,.faq{position:relative;isolation:isolate}
  .how::before,.sizes::before,.go::before,.price::before,.faq::before{
    content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
    /* top/auto 140% keeps the master's grassy bottom third outside every band */
    background:url("../img/limestone-900.webp") top/auto 140%;
    filter:grayscale(1);opacity:.055;
  }
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;overflow-x:clip}
body{
  margin:0;
  background:var(--bg);
  color:var(--ink);
  font-family:var(--f-body);
  font-size:var(--fs-base);
  line-height:1.62;
  font-weight:350;
  -webkit-font-smoothing:antialiased;
  overflow-x:clip;
}
img,svg,picture{display:block;max-width:100%}
img{height:auto}
a{color:inherit}
h1,h2,h3,h4{margin:0;font-family:var(--f-disp);font-weight:700;line-height:1.02;letter-spacing:-.028em;font-stretch:88%;font-variation-settings:'wdth' 88}
p{margin:0}
ul,ol,dl,dd{margin:0;padding:0}
li{list-style:none}
table{border-collapse:collapse;width:100%}

.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--amber);color:var(--on-amber);padding:var(--s3) var(--s5);font-family:var(--f-mono);font-size:var(--fs-ui)}
.skip:focus{left:12px;top:12px}

/* [tabindex] is load-bearing: .reel is a div[tabindex="0"], so removing its
   own focus override without adding [tabindex] here would drop it to the UA
   default ring, not the brand ring. :where() keeps specificity 0. */
:where(a,button,summary,input,[tabindex]):focus-visible{
  outline:2px solid var(--accent-ink);
  outline-offset:3px;
  border-radius:2px;
}

.wrap{width:100%;max-width:var(--wrap);margin-inline:auto;padding-inline:var(--pad)}

/* ── the horizon: how light hands over to dark ─────────────────────────
   Hard cuts between sections are template work. Each deep band is
   introduced by a horizon — a sea-coloured line with a short bleed above
   it, the way water meets light. One device, used only where the page
   actually changes state. */
.horizon{position:relative;height:0}
.horizon::before{
  content:"";position:absolute;left:0;right:0;bottom:0;height:120px;
  background:linear-gradient(180deg,rgba(11,32,39,0) 0%,rgba(11,32,39,.06) 55%,rgba(11,32,39,.16) 100%);
  pointer-events:none;
}
.horizon::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--deep-sea) 22%,var(--deep-sea) 78%,transparent);
  opacity:.55;
}

/* ── shared type ────────────────────────────────────────────────────── */
.eyebrow{
  font-family:var(--f-mono);
  font-size:var(--fs-label);
  letter-spacing:.17em;
  text-transform:uppercase;
  color:var(--ink-3);
  display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;
  margin-bottom:var(--s5);
}
.eyebrow__dot{width:6px;height:6px;background:var(--amber);border-radius:50%;flex:none;box-shadow:0 0 0 4px rgba(240,166,60,.18)}
.eyebrow__coord{color:var(--ink-3)}   /* no opacity: these are the real coordinates, not a flourish */
/* The hero eyebrow carries a dot and no rule. As a wrapping flex row the dot
   is a flex item in its own right, so once the label wraps the dot is left
   stranded alone on the first line. Anchor it instead — only the ruled
   variant actually needs flex, for the ::after rule that fills the row. */
.eyebrow:not(.eyebrow--rule){display:block;position:relative;padding-left:var(--s4)}
.eyebrow:not(.eyebrow--rule) .eyebrow__dot{position:absolute;left:0;top:.42em}
.eyebrow:not(.eyebrow--rule) .eyebrow__coord{display:block;margin-top:var(--s2)}
.eyebrow--rule::after{content:"";flex:1;height:1px;background:var(--line);min-width:32px}
/* Demoted eyebrows. Three of the eight carried a unit or a basis that no
   heading holds; they keep the mono voice but move BELOW their heading and
   drop the uppercase + hairline device, so the eyebrow proper stays rare. */
.h2-note{font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.09em;color:var(--ink-3);margin-top:var(--s3)}

.h2{font-size:var(--fs-d2);max-width:17ch;font-weight:800;letter-spacing:-.032em}
.h2--wide{max-width:22ch}
/* display 800 against a 300 deck — the weight extreme is the contrast,
   not a size bump */
.body{color:var(--ink-2);max-width:var(--measure);margin-top:var(--s5);font-weight:320}
/* .body--intro is now identical to .body and is intentionally left inert —
   the class stays in the markup, the size distinction does not. */
/* the one lifted line in a passage — accent-ink resolves to burnt amber on a
   sun band and to bright amber on a deep one, so it never fails either way */
.body--amber{color:var(--accent-ink);font-weight:400}
.body strong{font-weight:600;color:var(--ink)}

.num{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-weight:400}
.num__u{font-size:.5em;margin-left:.28em;color:var(--ink-3);letter-spacing:.06em}

/* ── buttons ────────────────────────────────────────────────────────── */
.btn{
  /* .btn is the COMPACT variant — nav CTA and the mobile bar. The primary
     spec is .btn--lg (hero, closing CTA band). Two specs, no third. */
  display:inline-flex;align-items:center;justify-content:center;gap:var(--s2);
  font-family:var(--f-mono);font-size:var(--fs-ui);letter-spacing:.12em;text-transform:uppercase;
  text-decoration:none;padding:var(--s3) var(--s5);border:1px solid transparent;
  transition:background .22s var(--ease),color .22s var(--ease),border-color .22s var(--ease),transform .22s var(--ease);
  white-space:nowrap;
}
/* the PRIMARY button spec. One size for the money CTA everywhere it appears:
   hero ×2 and the closing band. Differentiated from .btn by padding only —
   both sit on --fs-ui, so there is exactly one button type size on the page. */
.btn--lg{padding:var(--s4) var(--s6)}
.btn--amber{background:var(--amber);color:var(--on-amber);font-weight:500}
.btn--amber:hover{background:var(--amber-hi);transform:translateY(-2px)}
.btn--amber:active{transform:translateY(0)}
.btn--ghost{border-color:var(--edge);color:var(--ink)}
.btn--ghost:hover{border-color:var(--ink);background:rgba(10,31,38,.045)}
.band--deep .btn--ghost:hover{background:rgba(237,241,240,.06)}

/* ── boot curtain ───────────────────────────────────────────────────── */
.boot{position:fixed;inset:0;z-index:300;background:var(--sun-bg);display:grid;place-items:center;transition:clip-path .7s var(--ease-in)}
.boot__bar{width:min(240px,42vw);height:2px;background:rgba(10,31,38,.15);position:relative;overflow:hidden}
.boot__bar::after{content:"";position:absolute;inset:0;background:var(--amber);transform:scaleX(0);transform-origin:left;animation:bootfill .62s var(--ease) forwards}
@keyframes bootfill{to{transform:scaleX(1)}}
.boot.is-done{clip-path:inset(0 0 100% 0);pointer-events:none}

/* ── nav ────────────────────────────────────────────────────────────── */
.nav{position:fixed;inset:0 0 auto;z-index:100;color:var(--sun-ink);transition:background .3s var(--ease),border-color .3s var(--ease),backdrop-filter .3s,transform .45s var(--ease)}
/* soft hide on scroll-down, return on scroll-up — keyboard users always get it back */
.nav.is-away{transform:translateY(-110%)}
.nav:focus-within{transform:none}
.nav__in{max-width:var(--wrap);margin-inline:auto;padding:var(--s4) var(--pad);display:flex;align-items:center;gap:var(--s6)}
.nav::after{content:"";position:absolute;inset:auto 0 0;height:1px;background:transparent;transition:background .3s var(--ease)}
.nav{transition:background .3s var(--ease),border-color .3s var(--ease),backdrop-filter .3s,transform .45s var(--ease),inset .5s var(--ease),border-radius .5s var(--ease),box-shadow .4s var(--ease)}
/* The floating rounded island is the second-most-copied nav shape on the web
   and it was the only 999px radius on an otherwise square page. Square,
   full-bleed, one hairline — a signage rail. .nav::after is already built as
   that hairline; it just needed switching on. */
.nav.is-stuck{
  background:var(--scrim);backdrop-filter:blur(14px) saturate(140%);
}
.nav.is-stuck::after{background:var(--line)}
.nav.is-stuck .nav__in{padding-block:var(--s2)}

/* 17px is a deliberate scale exception: bumping to --fs-strong (17.5) widens
   the wordmark ~2px and worsens the pre-existing 360px lang-pill clip. */
.brand{display:flex;align-items:center;gap:var(--s2);text-decoration:none;font-family:var(--f-disp);font-weight:700;font-size:17px;letter-spacing:-.02em;flex:none}
.brand__mark{color:var(--sun-amber-ink);display:flex}
.brand__place{color:var(--sun-ink-2);font-weight:500}
.brand__word{color:var(--sun-ink)}

/* De-template: the links leave the right-hand cluster and dock against the
   wordmark behind the hinge gap from the C1/C3 marks — a 1px rule interrupted
   at its middle. Rendered inside the existing --s6 flex gap, so it costs zero
   layout width (the rail is already within 21px of full at 1081px in Greek). */
.nav__links{display:flex;gap:var(--s5);position:relative;font-family:var(--f-mono);font-size:var(--fs-ui);letter-spacing:.09em;text-transform:uppercase}
.nav__links::before{
  content:"";position:absolute;left:calc(var(--s6) / -2);top:-2px;bottom:-2px;width:1px;
  background:linear-gradient(180deg,var(--line) 0 36%,transparent 36% 64%,var(--line) 64% 100%);
}
/* 6px→12px is a rounding-rule EXCEPTION (up, not down): it takes the link
   hit area from 28px to 44px at zero layout cost, because the nav row height
   is set by the 46px CTA beside it. */
.nav__links a{text-decoration:none;color:var(--sun-ink-2);padding:var(--s3) 0;position:relative;transition:color .2s}
.nav__links a::after{content:"";position:absolute;left:0;bottom:0;width:100%;height:1px;background:var(--sun-amber-ink);transform:scaleX(0);transform-origin:right;transition:transform .3s var(--ease)}
.nav__links a:hover{color:var(--sun-ink)}
.nav__links a:hover::after{transform:scaleX(1);transform-origin:left}

.nav__end{display:flex;align-items:center;gap:var(--s4);margin-left:auto}
/* the C1 code-dot, restated on the one persistent desktop action. Amber stays
   the fill; the dot is on-amber ink, so BRAND.md rule 1 is untouched. */
.nav__cta-dot{width:5px;height:5px;border-radius:50%;background:var(--on-amber);flex:none}
/* the hinge-gap, same interrupted-rule device as .nav__links::before rotated
   90° — the tick length pins to --s4 so it clears the dot and label at any
   locale width (IT "Apri un armadietto" is longest) instead of a % split,
   which would run straight through short labels too. */
.nav__cta{position:relative}
.nav__cta::before{
  content:"";position:absolute;left:0;right:0;top:50%;height:1px;pointer-events:none;
  background:linear-gradient(90deg,var(--line) 0 var(--s4),transparent var(--s4) calc(100% - var(--s4)),var(--line) calc(100% - var(--s4)) 100%);
}
.nav__door{display:none}
/* ── language switcher ───────────────────────────────────────────────────
   Replaces the four-code rail (EN|SQ|IT|EL, 186.6px). Two failures it fixed:
   the rail showed four equal codes and never said which was ACTIVE at a
   glance, and "SQ"/"EL" are English abbreviations — unreadable to exactly the
   people who need them. The panel names each language in its own script.

   CLEARANCE, not taste: motion.js §7 gives .btn--amber a magnetic field of
   max(w,h)/2 + 56 and a strength of .32. For the 180×46 nav CTA that is a
   146px radius reaching 56px past its own left edge, and a maximum lunge of
   146 × .32 = 46.72px. Measured at 1440px, the old rail ended 16px from the
   CTA — so hovering EL pulled the amber button 41.7px left and buried 24.7px
   of the pill. The margin below holds the gap at --s7 (48px) > 46.72px, which
   is a hard bound: the CTA cannot reach the switcher at any cursor position.
   The magnet is additionally suspended outright while the panel is open
   (body.is-langopen, motion.js) — clearance stops overlap, but a button
   twitching beside an open menu still reads as broken. */
.langsw{position:relative;flex:none}
.langsw__btn{
  display:inline-flex;align-items:center;gap:var(--s2);
  background:none;border:1px solid var(--edge);color:var(--sun-ink-2);cursor:pointer;
  font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.1em;
  padding:var(--s2) 10px;position:relative;
  transition:color .2s var(--ease),border-color .2s var(--ease);
}
/* 44px hit area without layout bloat — the pill is 30px and the pseudo adds
   7px above and below, staying inside the nav row. Same technique the old
   rail used; unlike the old rail it can also expand HORIZONTALLY now, because
   there is one target here instead of four adjacent ones to mis-route between. */
.langsw__btn::after{content:"";position:absolute;inset:-7px -4px}
.langsw__btn:hover,.langsw__btn[aria-expanded="true"]{color:var(--sun-ink);border-color:var(--sun-ink)}
.langsw__code{line-height:1}
.langsw__caret{
  width:5px;height:5px;flex:none;margin-left:var(--s0);
  border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;
  transform:translateY(-2px) rotate(45deg);transition:transform .25s var(--ease);
}
.langsw__btn[aria-expanded="true"] .langsw__caret{transform:translateY(1px) rotate(-135deg)}

/* 18×12 keeps every flag on one tile width so the four read as a set. The
   inset hairline is load-bearing, not decoration: the white bands of the GB
   and GR flags would otherwise dissolve into the light nav with no edge. */
.langsw__flag{
  width:18px;height:12px;flex:none;display:block;position:relative;
  box-shadow:inset 0 0 0 1px rgba(10,31,38,.22);
}
.langsw__flag svg{display:block;width:100%;height:100%}

/* The panel borrows the mobile nav sheet's idiom exactly — deep ground, one
   hairline, square corners, hard shadow. It is an instrument panel, the same
   argument that licenses the dark split-flap board. No radius anywhere. */
.langsw__menu{
  position:absolute;top:calc(100% + 11px);right:0;z-index:10;
  min-width:198px;padding:var(--s1) 0;
  background:var(--deep-bg);
  border:1px solid rgba(237,241,240,.13);
  box-shadow:0 34px 80px -28px rgba(6,28,35,.75);
}
.langsw__menu[hidden]{display:none}
.langsw__opt{
  display:flex;align-items:center;gap:var(--s3);width:100%;
  min-height:44px;padding:0 var(--s4);
  background:none;border:0;cursor:pointer;text-align:left;
  color:var(--deep-ink-2);transition:color .18s var(--ease),background .18s var(--ease);
}
.langsw__opt:hover,.langsw__opt:focus-visible{color:var(--deep-ink);background:rgba(237,241,240,.055)}
.langsw__name{flex:1;font-family:var(--f-body);font-size:var(--fs-data);line-height:1}
.langsw__tag{font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.1em;color:var(--deep-ink-2);position:relative}
/* the C1 code-dot marks the active language — the same amber dot already used
   on the nav CTA and the logo mark, so "current" needs no new vocabulary */
.langsw__opt.is-on{color:var(--deep-ink)}
.langsw__opt.is-on .langsw__tag{color:var(--amber)}
.langsw__opt.is-on .langsw__tag::after{
  content:"";position:absolute;right:-11px;top:50%;translate:0 -50%;
  width:5px;height:5px;border-radius:50%;background:var(--amber);
}
.langsw__opt.is-on .langsw__flag{box-shadow:inset 0 0 0 1px rgba(240,166,60,.55)}
/* The berth itself: --s8, so 64px total with the rail's own --s4 gap.
   Sized from the WORST language, not from English. Measured at 1440px the nav
   CTA is 180px in English but 225px in Greek ("Ανοίξτε μια θυρίδα"), which
   pushed the lunge from 46.72px to 53.99px — a 48px berth held in English and
   failed in sq/it/el by up to 6px. 64px clears the worst measured case by 10px,
   and motion.js now caps any shift at 48px so the margin holds whatever a
   future translation does to the label. Desktop only: at ≤760 the CTA is
   display:none and the switcher sits beside the door button, where --s4 is right. */
@media (min-width:761px){
  .langsw{margin-right:calc(var(--s8) - var(--s4))}
  /* the berth reads as a division rather than dead air — the same interrupted
     hairline the nav links already use to dock against the wordmark */
  .langsw::after{
    content:"";position:absolute;right:calc(var(--s8) / -2);top:-7px;bottom:-7px;width:1px;
    background:linear-gradient(180deg,var(--line) 0 34%,transparent 34% 66%,var(--line) 66% 100%);
  }
}

/* ── 1 · hero ───────────────────────────────────────────────────────────
   The antithesis lives INSIDE the hero: a limestone plate (paper), a dark
   split-flap board (machine), floating on open turquoise water (place).
   The photograph is not dimmed into a mood — it stays bright, and the type
   gets its contrast from its own plate instead of from a scrim. */
.hero{position:relative;min-height:100svh;display:flex;align-items:center;padding:clamp(104px,13vh,150px) 0 clamp(56px,9vh,110px);overflow:hidden;background:var(--sun-bg)}
.hero__field{position:absolute;inset:0;z-index:0}
/* <picture> is the img's PARENT, so the img's height:100% resolved against a
   height:auto wrapper, not against the field — object-fit:cover never engaged
   and the photo drew at its natural 1.791 ratio. Invisible on desktop (it fell
   96px short under the bottom wash); on a phone it was a 218px strip. */
.hero__field picture{display:block;height:100%}
.hero__field img{width:100%;height:100%;object-fit:cover;filter:saturate(1.06) contrast(1.02)}
.hero__field::after{
  content:"";position:absolute;inset:0;
  /* only two jobs: keep the nav legible at the top, and land the section
     into the limestone field at the bottom. The middle stays untouched. */
  background:
    linear-gradient(180deg,rgba(238,242,241,.92) 0%,rgba(238,242,241,.35) 13%,rgba(238,242,241,0) 30%,rgba(238,242,241,0) 72%,rgba(238,242,241,.55) 90%,var(--sun-bg) 100%);
}
/* 1.2/.8, not 1.06/.94: at >=1240px the wrap is a constant 1128px, so the
   plate column is fixed and the h1 must fit inside it. Longest authored
   headline line across the four dictionaries is 10.67em (Greek "ανάμεσα στο
   check-out", measured in the system-ui fallback — Bricolage ships no Greek
   subset). 1.06fr gave the plate 470px inner against a 576px line. */
.hero__in{
  position:relative;z-index:1;width:100%;max-width:var(--wrap);margin-inline:auto;padding-inline:var(--pad);
  display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,.8fr);gap:clamp(28px,4vw,56px);align-items:center;
}
.hero__plate{
  background:var(--sun-surface);
  padding:clamp(28px,3.2vw,40px);
  box-shadow:0 1px 0 rgba(10,31,38,.06), 0 34px 70px -34px rgba(8,40,48,.5);
  border:1px solid rgba(10,31,38,.08);
}
/* max 50px, not 54: above 1282px the plate column stops growing (wrap caps at
   1240) while 3.9vw kept growing to 54px — that gap IS the orphan. 50px leaves
   >=4.7% slack on the longest line in all four languages. */
.hero__h{font-size:var(--fs-d1);font-weight:800;letter-spacing:-.035em;margin-bottom:var(--s5);hyphens:none;color:var(--sun-ink)}
.hero__h span{display:block}
.hero__h .ln{display:block;overflow:hidden}
.hero__h .ln > i{display:block;font-style:normal}
/* Belt and braces for the Greek fallback: Bricolage has no Greek subset, so
   EL headline widths depend on whichever system-ui the visitor's OS supplies.
   If one ever exceeds the plate, balance splits it evenly instead of leaving a
   one-word orphan. site.js rewraps each span's text into a block <i>, so the
   property has to sit on both. */
.hero__h span,.hero__h .ln > i{text-wrap:balance}
.lede{color:var(--sun-ink-2);font-size:var(--fs-lede);max-width:var(--measure-n);line-height:1.58;font-weight:320}
.hero__cta{display:flex;gap:var(--s3);flex-wrap:wrap;margin-top:var(--s6)}
.hero__note{font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.09em;text-transform:uppercase;color:var(--sun-ink-3);margin-top:var(--s4)}
.hero__scroll{position:absolute;left:50%;bottom:22px;translate:-50% 0;width:1px;height:44px;background:rgba(10,31,38,.2);overflow:hidden;z-index:1}
.hero__scroll span{position:absolute;inset:0;background:var(--sun-amber-ink);animation:scrollpulse 2.4s var(--ease) infinite}
@keyframes scrollpulse{0%{transform:translateY(-100%)}60%,100%{transform:translateY(100%)}}

/* ── signature: split-flap departure board ────────────────────────────
   The one elaborate thing on the page. It is a dark machine and it stays
   dark on every band — that is precisely why it reads now. */
.board{
  /* the flat colour is not decoration: if the gradient fails to paint, the
     board's light text would otherwise land on the limestone band */
  background-color:#0F2A35;
  background-image:linear-gradient(180deg,#0F2A35,#081D24);
  border:1px solid rgba(237,241,240,.13);
  box-shadow:0 34px 80px -28px rgba(6,28,35,.75), inset 0 1px 0 rgba(237,241,240,.06);
  padding:var(--s5) clamp(16px,2vw,26px) var(--s4);
  /* the flap seam. Full weight is craft at 17px flaps; at the 14px floor a
     .9-alpha near-black hairline lands on the cap midline and reads as a
     strikethrough through every board word. */
  --fl-seam:rgba(6,22,28,.25);
}
.board__head{
  display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
  font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.19em;text-transform:uppercase;color:var(--amber);
  padding-bottom:var(--s3);border-bottom:1px solid rgba(237,241,240,.13);
}
.board__lamp{width:7px;height:7px;border-radius:50%;background:var(--amber);flex:none;animation:lamp 3.2s ease-in-out infinite}
@keyframes lamp{0%,100%{opacity:1;box-shadow:0 0 0 0 rgba(240,166,60,.5)}50%{opacity:.32;box-shadow:0 0 0 6px rgba(240,166,60,0)}}
.board__cols{
  display:grid;grid-template-columns:1fr calc(4ch + 6px) calc(6ch + 10px);gap:0 clamp(10px,1.6vw,22px);
  font-family:var(--f-mono);font-size:var(--fs-flap);letter-spacing:.2em;text-transform:uppercase;
  color:var(--deep-ink-3);padding:var(--s2) 0 var(--s2);
}
.board__cols span{font-size:var(--fs-label)}
.board__cols span:nth-child(2),.board__cols span:nth-child(3){text-align:left}
/* rounding-rule EXCEPTION (up, not down): the flap rows must stay visually
   separated at the small flap size — rounding 6→4 closes the rail gap. */
.board__rows{display:flex;flex-direction:column;gap:var(--s2)}
.board__row{display:grid;grid-template-columns:1fr calc(4ch + 6px) calc(6ch + 10px);gap:0 clamp(10px,1.6vw,22px);align-items:center;font-family:var(--f-mono);font-size:var(--fs-flap)}
.board__grp{display:flex;gap:2px}
.board__foot{
  display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;
  font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.14em;text-transform:uppercase;white-space:nowrap;
  color:var(--deep-ink-3);margin-top:var(--s4);padding-top:var(--s3);border-top:1px solid rgba(237,241,240,.08);
}
.board__foot-r{color:var(--deep-ink-2)}

.fl{
  position:relative;display:inline-block;
  width:1ch;height:1.34em;line-height:1;
  font-family:var(--f-mono);font-weight:500;
  /* floor raised 11 -> 14: the seam sits at the flap's vertical midline at ANY
     size, so the only thing size buys is a thinner line relative to the cap.
     14px was verified to fit: a row is 21ch + 2 gaps = 196px against 246px of
     board interior at a 320px viewport. The board first overflows at 16px. */
  font-size:var(--fs-flap);
  perspective:220px;
}
.fl-h{position:absolute;left:0;right:0;height:50%;overflow:hidden;background:#163947;display:block}
.fl-h i{
  position:absolute;left:0;right:0;height:1.34em;line-height:1.34em;text-align:center;
  font-style:normal;color:var(--deep-ink);
}
.fl-top{top:0;border-radius:2px 2px 0 0;background:#163947}
.fl-top i{top:0}
.fl-bot{bottom:0;border-radius:0 0 2px 2px;background:#163947;border-top:1px solid var(--fl-seam)}
.fl-bot i{bottom:0}
.fl-fold{z-index:2;backface-visibility:hidden}
.fl-fold.fl-top{transform-origin:bottom;animation:foldTop .052s linear forwards;background:#193F4E}
.fl-fold.fl-bot{transform-origin:top;transform:rotateX(90deg);animation:foldBot .052s linear .052s forwards;background:#112E39}
@keyframes foldTop{from{transform:rotateX(0)}to{transform:rotateX(-90deg)}}
@keyframes foldBot{from{transform:rotateX(90deg)}to{transform:rotateX(0)}}
.fl--amber .fl-h i{color:var(--amber)}
.fl--dim .fl-h i{color:var(--deep-ink-2)}
/* an unused flap on a real board is still a flap — visible, but it must not
   read as a block of noise beside the word it follows */
.fl--blank .fl-top{background:#0F2A35}
.fl--blank .fl-bot{background:#0B222B}

/* ── 2 · fact strip ─────────────────────────────────────────────────── */
.strip{border-block:1px solid var(--line);background:var(--surface-2)}
.strip__in{
  max-width:var(--wrap);margin-inline:auto;padding-inline:var(--pad);
  display:grid;grid-template-columns:repeat(4,1fr);
}
.strip__in li{padding:var(--s6) var(--s5) var(--s6) 0;display:flex;flex-direction:column;gap:var(--s2)}
.strip__in li + li{border-left:1px solid var(--line-2);padding-left:var(--s5)}
.strip .num{font-size:var(--fs-d4);color:var(--ink);letter-spacing:-.02em}
/* 24ch is a column-constrained micro-caption in a 4-up grid, not a prose
   measure — deliberately outside --measure/--measure-n. */
.strip span{font-size:var(--fs-data);color:var(--ink-2);line-height:1.45;max-width:24ch;font-weight:320}

/* ── 3 · the gap (deep band — the problem) ──────────────────────────── */
.gap{padding-block:var(--sec)}
.gap__grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.85fr);gap:clamp(36px,6vw,88px);align-items:center}
.timeline{margin:0;padding-top:var(--s3)}
/* The line lives in ::before, not on the track box. The tick labels are
   absolutely-positioned children; an opaque background on the track itself
   makes every contrast tool resolve their background to the 2px rule they
   sit beside rather than the band behind them. */
.timeline__track{position:relative;height:2px;margin:var(--s7) 0 var(--s9)}
.timeline__track::before{content:"";position:absolute;inset:0;background:var(--edge)}
.timeline__fill{position:absolute;inset:0;background:linear-gradient(90deg,var(--amber),rgba(240,166,60,.25));transform-origin:left;transform:scaleX(0)}
.timeline__tick{position:absolute;left:var(--at);top:0;translate:-50% 0}
.timeline__tick::before{content:"";position:absolute;left:50%;top:-7px;width:1px;height:16px;background:var(--ink-3);translate:-50% 0}
.timeline__tick b{position:absolute;left:50%;bottom:var(--s4);translate:-50% 0;font-family:var(--f-mono);font-size:var(--fs-data);color:var(--ink);font-weight:400}
.timeline__tick i{position:absolute;left:50%;top:var(--s4);translate:-50% 0;font-style:normal;font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3);white-space:nowrap}
/* .timeline__fill is also a span, so the first tick is span:nth-of-type(2);
   desktop keeps it center-anchored — the left-align lives in the ≤760 query */
.timeline__tick:last-of-type i,.timeline__tick:last-of-type b{left:auto;right:0;translate:0 0;text-align:right}
/* nth-of-type(4) is the 17:00 tick. At the TRUE 85.7% its centred label runs
   41px into the right-anchored 18:00 label (at the old, wrong 74% it did not).
   Right-anchor it to its own tick, same device as the last tick. */
@media (min-width:761px){
  .timeline__tick:nth-of-type(4) i,.timeline__tick:nth-of-type(4) b{left:auto;right:0;translate:0 0;text-align:right}
}
.timeline__cap{display:flex;align-items:baseline;gap:var(--s3);border-top:1px solid var(--line);padding-top:var(--s4);font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}
.timeline__hrs{font-family:var(--f-disp);font-size:var(--fs-num-xl);line-height:.85;color:var(--accent-ink);font-weight:800}

/* ── 4 · how it works ───────────────────────────────────────────────── */
.how{padding-block:var(--sec)}
/* how — editorial scrollytelling: steps scroll past a sticky signage frame.
   The frame is a deep-band panel; the plates inherit its ink via currentColor. */
.sr-defs{position:absolute;width:0;height:0;overflow:hidden}
.story{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);gap:clamp(28px,5vw,72px);margin-top:var(--s7)}
.steps{list-style:none;margin:0;padding:0}
.step{min-height:clamp(300px,38vh,420px);display:flex;flex-direction:column;justify-content:center;border-top:1px solid var(--line-2);padding:var(--s6) 0}
.step:first-child{border-top:0}
.step__n{font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.14em;color:var(--ink-3);display:block;margin-bottom:var(--s5);transition:color .4s}
.step.is-active .step__n{color:var(--accent-ink)}
.step__h{font-size:var(--fs-d5);margin-bottom:var(--s3);letter-spacing:-.02em}
.step__p{color:var(--ink-2);font-size:var(--fs-prose);line-height:1.6;font-weight:320;max-width:var(--measure-n)}
.step__figure{display:none;margin:var(--s5) 0 0;background:var(--deep-bg);color:var(--deep-ink);border-radius:2px;overflow:hidden}
.step__figure svg{display:block;width:100%;height:auto}
/* the step photos are portrait devices — a phone screen, a locker door. They
   keep their own aspect: cropping one to a box ratio cuts the number plate off. */
.step__figure img{display:block;width:100%;height:auto}
.media-col{position:relative}
.media{--mediaH:clamp(340px,58vh,540px);position:sticky;top:calc((100svh - var(--mediaH))/2);height:var(--mediaH);border-radius:2px;overflow:hidden;background:var(--deep-bg);color:var(--deep-ink);border:1px solid rgba(237,241,240,.08)}
.media__plate{position:absolute;inset:0;display:grid;place-items:center;padding:clamp(20px,4vh,44px);visibility:hidden;background:var(--deep-bg)}
.media__plate.is-front{visibility:visible}
.media__plate svg{width:min(100%,calc(var(--mediaH)*1.15));max-height:100%;height:auto}
/* Portrait device shots inside a landscape-ish frame: contain, not cover.
   Cover crops the amber number plate off the top. The frame is a deep panel,
   so the margins either side read as the panel, not as letterboxing. */
.media__plate img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;user-select:none}
.media__cap{position:absolute;left:var(--s4);bottom:var(--s3);z-index:20;font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.15em;text-transform:uppercase;color:var(--deep-ink-2);background:rgba(11,32,39,.72);padding:var(--s2) var(--s3);border-radius:2px}

.assure{display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:var(--s5);margin-top:var(--s8);border-top:1px solid var(--line)}
.assure__item{display:contents}
.assure__n{font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.14em;color:var(--accent-ink);min-width:3ch;padding:var(--s6) 0 var(--s5);border-bottom:1px solid var(--line-2)}
.assure__body{padding:var(--s6) 0 var(--s5);border-bottom:1px solid var(--line-2)}
.assure__body h4{font-family:var(--f-body);font-weight:600;font-size:var(--fs-prose);letter-spacing:0;line-height:1.4;margin-bottom:var(--s2);color:var(--ink)}
.assure__body p{color:var(--ink-2);font-size:var(--fs-data);line-height:1.55;font-weight:320}

/* ── 5 · sizes ──────────────────────────────────────────────────────── */
.sizes{padding-block:var(--sec)}
.sizecard-row{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line-2);margin-top:var(--s8);border:1px solid var(--line)}
.sizecard{background:var(--surface);padding:var(--s6) var(--s5) var(--s6);display:flex;flex-direction:column;gap:var(--s5)}
.sizecard--hero{background:var(--surface-2)}
.sizecard__viz{display:flex;justify-content:center}
.szsvg{width:100%;max-width:196px;height:auto}
.szsvg__box{fill:color-mix(in srgb,var(--sea) 7%,transparent);stroke:var(--ink-3);stroke-width:1.6}
.sizecard--hero .szsvg__box{fill:rgba(240,166,60,.14);stroke:var(--accent-ink)}
.szsvg__handle{stroke:var(--ink-3);stroke-width:2.4;stroke-linecap:round}
.sizecard--hero .szsvg__handle{stroke:var(--accent-ink)}
.szsvg__floor{stroke:var(--line);stroke-width:1}
.szsvg__dim{stroke:var(--ink-3);stroke-width:1;stroke-dasharray:2 3}  /* dimension lines carry the measurement — not faded */
.szsvg__t{font-family:var(--f-mono);font-size:11px;fill:var(--ink-3)}
.sizecard__code{font-family:var(--f-disp);font-size:var(--fs-d3);font-weight:800;line-height:1;letter-spacing:-.03em;color:var(--ink)}
.sizecard--hero .sizecard__code{color:var(--accent-ink)}
.sizecard__dim{font-family:var(--f-mono);font-size:var(--fs-data);color:var(--ink);margin-top:var(--s2);font-variant-numeric:tabular-nums}
.sizecard__dim span{color:var(--ink-3)}
.sizecard__qty{font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.15em;text-transform:uppercase;color:var(--ink-3);margin-top:var(--s1)}
.sizecard__qty b{color:var(--ink);font-weight:500}
.sizecard__fit{color:var(--ink-2);font-size:var(--fs-data);line-height:1.5;margin-top:var(--s4);border-top:1px solid var(--line-2);padding-top:var(--s4);font-weight:320}
.sizes__foot{color:var(--ink-2);font-size:var(--fs-data);max-width:var(--measure);margin-top:var(--s5);font-weight:320}

/* ── 6 · map (deep band — the chart) ────────────────────────────────── */
.map{padding-block:var(--sec)}
.map__grid{display:grid;grid-template-columns:minmax(0,.78fr) minmax(0,1.22fr);gap:clamp(32px,5vw,72px);align-items:stretch}
.map__facts{margin-top:var(--s6);border-top:1px solid var(--line);display:grid;grid-template-columns:auto 1fr;column-gap:var(--s4)}
.map__facts div{display:contents}
/* 11ch is a label-column width, not a prose measure — excluded by design. */
.map__facts dt{font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);padding:var(--s4) 0 var(--s3);border-bottom:1px solid var(--line-2);min-width:11ch}
.map__facts dd{font-size:var(--fs-data);color:var(--ink);line-height:1.45;padding:var(--s3) 0;border-bottom:1px solid var(--line-2)}
.map__caveat{font-size:var(--fs-data);color:var(--ink-3);line-height:1.5;margin-top:var(--s5);max-width:var(--measure-n)}

.chart{margin:0;border:1px solid var(--line);background:#F4EDDF;display:flex;flex-direction:column}
/* live MapLibre map — tiles, glyphs and library all served with the site.
   The "paper" palette makes it a lit panel inside the deep band: legible in
   sun, which is where this audience actually reads it. #F4EDDF is the map's
   own land colour, so the panel never flashes a different shade while tiles
   are still arriving. */
.portmap{position:relative;width:100%;aspect-ratio:820/520;min-height:320px;background:#F4EDDF}
/* Two-column range only: the figure stretches to the copy column, so the map
   ends level with the last line of text instead of stopping short of it. */
@media (min-width:1081px){.portmap{aspect-ratio:auto;flex:1 1 auto;min-height:460px}}
@media (max-width:760px){.portmap{aspect-ratio:4/5}}
.portmap canvas{display:block;outline:none}
/* Google opt-in. Top-left is the only corner MapLibre leaves free — zoom
   controls take top-right and the attribution pill takes bottom-right, which
   the button collided with at phone width. z-index 3 clears the marker layer
   so it can never end up under the locker card. */
.portmap__gbtn{position:absolute;left:12px;top:12px;z-index:3;
  font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.12em;text-transform:uppercase;
  color:var(--amber);background:rgba(11,32,39,.92);border:1px solid rgba(240,166,60,.55);
  border-radius:2px;padding:10px 14px;cursor:pointer;line-height:1.2;
  min-height:44px;transition:background var(--t) var(--ease),border-color var(--t) var(--ease)}
.portmap__gbtn:hover,.portmap__gbtn:focus-visible{background:rgba(11,32,39,.99);border-color:var(--amber)}
@media (max-width:520px){.portmap__gbtn{left:8px;top:8px;padding:9px 11px;letter-spacing:.08em}}
.portmap__gframe{display:block;width:100%;height:100%;border:0}
.portmap__fallback{position:absolute;inset:0;display:grid;place-items:center;font-family:var(--f-mono);font-size:var(--fs-data);letter-spacing:.12em;line-height:2;color:#3C4F57;text-align:center;padding:var(--s5)}
/* controls sit on the paper panel, so they are light with dark ink */
.portmap .maplibregl-ctrl-group{background:rgba(255,255,255,.92);border:1px solid rgba(60,79,87,.2);border-radius:2px;box-shadow:none}
.portmap .maplibregl-ctrl-group button{width:34px;height:34px}
.portmap .maplibregl-ctrl-group button+button{border-top:1px solid rgba(60,79,87,.14)}
.portmap .maplibregl-ctrl.maplibregl-ctrl-attrib{background:rgba(255,255,255,.8);font-family:var(--f-mono);font-size:10px;color:#5A6E76}
.portmap .maplibregl-ctrl.maplibregl-ctrl-attrib a{color:#3C4F57}
.portmap .maplibregl-cooperative-gesture-screen{background:rgba(11,32,39,.7);color:var(--deep-ink);font-family:var(--f-mono);font-size:var(--fs-data);letter-spacing:.06em}
/* the locker marker — amber signage tile with the logo's code-dot */
.pmk{display:grid;justify-items:center;row-gap:6px;cursor:default;text-align:center}
.pmk__card{font-family:var(--f-mono);font-size:11px;letter-spacing:.11em;color:var(--amber);background:rgba(11,32,39,.88);border:1px solid rgba(240,166,60,.5);border-radius:2px;padding:7px 10px 6px;white-space:nowrap}
.pmk__sub{display:block;font-size:9.5px;letter-spacing:.09em;color:var(--deep-ink-2);margin-top:3px}
/* on a phone the street line is redundant — it sits in the facts list above,
   and dropping it keeps the signage card clear of the map edges */
@media (max-width:760px){.pmk__sub{display:none}}
/* The 132px cap that used to live here was sized when the card still carried
   its street sub-line. With that line hidden below 760px the card is 233px on
   one line, and the map is 348px wide at a 390px phone — measured, not
   estimated — so it fits, and the cap was breaking "LUGGAGE LOCKERS" over
   three lines for nothing. Only the narrowest phones need the type to step
   down; MapLibre's own overflow:hidden is what would clip it. */
@media (max-width:620px){
  .pmk__card{white-space:nowrap;max-width:none;padding:6px 8px 5px}
}
@media (max-width:400px){
  .pmk__card{font-size:10px;letter-spacing:.08em}
}
.pmk__pin{width:14px;height:18px;background:var(--amber);border-radius:2px;position:relative}
.pmk__pin::after{content:"";position:absolute;right:2.5px;bottom:2.5px;width:3.5px;height:3.5px;border-radius:50%;background:#0B2027}
.pmk__pin::before{content:"";position:absolute;inset:-8px;border:1px solid rgba(240,166,60,.45);border-radius:4px;animation:pmkping 3.4s var(--ease) infinite}
@media (prefers-reduced-motion:reduce){.pmk__pin::before{animation:none}}
@keyframes pmkping{0%{transform:scale(.6);opacity:1}70%,100%{transform:scale(1.6);opacity:0}}
.chart__cap{font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);padding:var(--s3) var(--s4);border-top:1px solid var(--line);background:var(--surface);display:flex;justify-content:space-between;align-items:baseline;gap:var(--s4);flex-wrap:wrap}
.chart__dir{color:var(--amber);text-decoration:none;border-bottom:1px solid rgba(240,166,60,.4);white-space:nowrap}
.chart__dir:hover,.chart__dir:focus-visible{border-bottom-color:var(--amber)}

/* ── 7 · where you'll go ───────────────────────────────────────────────
   Was a text table. The six places Saranda is actually visited FOR cannot
   be a table — they are the reason the afternoon is worth buying back.
   Each is a plate: a photograph when one exists, and until then a real
   bearing-and-distance diagram computed from the locker's own coordinates,
   which is information rather than a grey box waiting for an image. */
.go{padding-block:var(--sec)}
/* go — draggable velocity-skew reel (Snellenberg/Osmo pattern, scoped to its
   own viewport so the page keeps normal vertical scroll) */
/* user-select is load-bearing, not cosmetic: without it a pointer drag across
   the track is also a text selection, so the cards and photos flood with the
   ::selection colour and the cursor flips to the I-beam/no-drop ghost. */
.reel{position:relative;margin-top:var(--s8);overflow:hidden;cursor:grab;touch-action:pan-y;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;mask-image:linear-gradient(90deg,#000 0%,#000 calc(100% - var(--s7)),transparent);-webkit-mask-image:linear-gradient(90deg,#000 0%,#000 calc(100% - var(--s7)),transparent)}
/* offset only — the colour now comes from the global ring, which .reel
   reaches via [tabindex]. 6px of clearance is kept because the track has
   2px padding and the slides skew on drag. */
.reel:focus-visible{outline-offset:6px}
.reel.is-drag{cursor:grabbing}
.reel__track{display:flex;gap:clamp(16px,2.5vw,28px);width:max-content;will-change:transform;padding:2px}
.slide{flex:0 0 auto;width:clamp(280px,31vw,470px);margin:0;background:var(--surface);border:1px solid var(--line);transform:skewX(var(--skew,0deg)) scale(var(--sc,1));will-change:transform}
.slide__ph{overflow:hidden;aspect-ratio:4/3;background:var(--surface-2)}
.slide__ph img{width:100%;height:100%;object-fit:cover;display:block;pointer-events:none;-webkit-user-drag:none}
.slide__cap{display:flex;gap:var(--s4);padding:var(--s4) var(--s4) var(--s5);transform:translateX(var(--par,0px))}
.slide__cap .place__rose{position:static;width:104px;height:78px;flex:0 0 104px;order:2;align-self:flex-start;margin-top:var(--s1)}
.slide__t{flex:1;min-width:0;order:1}
.slide__idx{font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.16em;color:var(--accent-ink);text-transform:uppercase;display:block;margin-bottom:var(--s2)}
.slide__h{font-size:var(--fs-d5);font-weight:800;letter-spacing:-.028em;color:var(--ink)}
.slide__p{color:var(--ink-2);font-size:var(--fs-data);line-height:1.5;margin-top:var(--s2);font-weight:320;min-height:calc(1.5em * 3)}
.slide__spec{margin-top:var(--s2);font-family:var(--f-mono);font-size:var(--fs-label);color:var(--ink);border-top:1px solid var(--line-2);padding-top:var(--s2);font-variant-numeric:tabular-nums}
.slide__spec--2{margin-top:var(--s1);border-top:0;padding-top:0;color:var(--ink-2)}
.reel__meta{display:flex;justify-content:space-between;align-items:center;margin-top:var(--s5)}
.reel__progress{width:160px;height:2px;background:var(--line)}
.reel__progress i{display:block;height:100%;background:var(--accent-ink);transform:scaleX(0);transform-origin:left}
.reel__hint{font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
.reel__hint--touch{display:none}
@media (pointer:coarse){
  .reel__hint--drag{display:none}
  .reel__hint--touch{display:block}
}
.rose__ring{fill:none;stroke:var(--line);stroke-width:1}
.rose__tick{stroke:var(--line);stroke-width:1}
/* MEASURED: 7 user units × 0.65 (104px box) = 4.55px, × 0.55 (88px box) = 3.85px.
   These cannot be promoted: at ≥15u the "N" glyph at y=7.5 overflows the top
   of the 160×120 viewBox, so a legible size needs the markup repositioned.
   Hidden is the honest fix; the needle + the SVG aria-label still carry the
   bearing. */
.rose__card{display:none}
.rose__needle{stroke:var(--accent-ink);stroke-width:1.6;stroke-linecap:round}
.rose__head{fill:var(--accent-ink)}
.rose__hub{fill:none;stroke:var(--ink-3);stroke-width:1}
/* 19 user units × 0.55 (the 88px mobile box) = 10.45px rendered, × 0.65
   (104px desktop) = 12.35px. The unit is differentiated by fill and tracking
   instead of by size — a smaller tspan cannot clear the 10px floor. */
.rose__km{font-family:var(--f-mono);font-size:19px;fill:var(--ink);letter-spacing:.02em}
.rose__km tspan{fill:var(--ink-3);letter-spacing:.14em}
/* The bearing datum left the SVG entirely (it measured 4.13px rendered there,
   width-bound at 25 chars across ~146 of 160 units) and now lives as a real
   .slide__spec--2 line in each caption, where it is readable and translated. */
.slide__h .badge{
  display:inline-block;font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.16em;font-weight:400;
  color:var(--accent-ink);border:1px solid currentColor;padding:var(--s0) var(--s2);vertical-align:middle;margin-left:var(--s2);translate:0 -3px;
}
.go__note{font-size:var(--fs-data);color:var(--ink-3);line-height:1.5;margin-top:var(--s5);max-width:var(--measure)}

.warn{display:flex;gap:var(--s4);margin-top:var(--s7);border-left:2px solid var(--accent-ink);padding:var(--s4) var(--s5);max-width:var(--measure);background:linear-gradient(90deg,rgba(240,166,60,.13),transparent)}
.warn__k{font-family:var(--f-mono);color:var(--accent-ink);font-size:var(--fs-d6);line-height:1.2;flex:none}
.warn h3{font-family:var(--f-body);font-size:var(--fs-strong);font-weight:600;letter-spacing:0;line-height:1.35;margin-bottom:var(--s2);color:var(--ink)}
.warn p{color:var(--ink-2);font-size:var(--fs-prose);line-height:1.55;font-weight:320}

/* ── 8 · price ──────────────────────────────────────────────────────── */
.price{padding-block:var(--sec)}
.price__head{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:clamp(24px,4vw,64px);align-items:end}
.price__from{
  font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.15em;text-transform:uppercase;color:var(--ink-3);
  border-left:2px solid var(--accent-ink);padding-left:var(--s4);line-height:1.5;white-space:nowrap;
}
.price__from b{display:block;font-family:var(--f-disp);font-size:var(--fs-num-lg);line-height:.92;color:var(--accent-ink);letter-spacing:-.03em;font-weight:800}
.price__from i{display:block;font-style:normal;font-size:var(--fs-label);color:var(--ink-3);letter-spacing:.12em}

.tbl-scroll{overflow-x:auto;margin-top:var(--s8);-webkit-overflow-scrolling:touch}
.swipe{display:none}
@media (max-width:760px){
  .swipe{
    display:block;font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.13em;text-transform:uppercase;
    color:var(--accent-ink);margin-top:var(--s7);margin-bottom:calc(var(--s5) * -1);
  }
  .swipe + .tbl-scroll{margin-top:var(--s5);mask-image:linear-gradient(90deg,#000 calc(100% - var(--s6)),transparent);-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - var(--s6)),transparent)}
}
.rates{min-width:620px}
.rates th,.rates td{padding:var(--s4) var(--s4) var(--s4) 0;border-bottom:1px solid var(--line-data);text-align:right;vertical-align:baseline}
.rates thead th{border-bottom:1px solid var(--line);text-align:right;padding-bottom:var(--s3);font-weight:400}
.rates thead th:first-child{text-align:left}
.rates__sz{display:block;font-family:var(--f-disp);font-size:var(--fs-d6);font-weight:700;color:var(--ink);letter-spacing:-.02em}
.rates__wh{display:block;font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.09em;color:var(--ink-3);margin-top:var(--s1)}
.rates thead th:first-child{font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.18em;text-transform:uppercase;color:var(--ink-3);vertical-align:bottom}
.rates tbody th{
  text-align:left;font-family:var(--f-mono);font-size:var(--fs-data);font-weight:400;color:var(--ink);
  letter-spacing:.04em;white-space:nowrap;
}
.rates tbody td b{display:block;font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:var(--fs-strong);font-weight:500;color:var(--ink)}
.rates tbody td i{display:block;font-style:normal;font-family:var(--f-mono);font-size:var(--fs-label);color:var(--ink-3);margin-top:var(--s0)}
.rates tr.rates--pick{background:rgba(240,166,60,.18)}
.rates tr.rates--pick td b{color:var(--accent-ink)}
.tag{
  display:inline-block;font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.16em;text-transform:uppercase;
  color:var(--accent-ink);border:1px solid currentColor;padding:var(--s0) var(--s2);
  vertical-align:middle;margin-left:var(--s2);translate:0 -2px;
}
.rates__note{font-size:var(--fs-data);color:var(--ink-3);line-height:1.5;margin-top:var(--s4);max-width:var(--measure)}

.cta-band{
  margin-top:var(--s9);border:1px solid var(--line);background:var(--surface);
  padding:clamp(28px,4vw,52px);display:flex;align-items:center;justify-content:space-between;gap:var(--s6);flex-wrap:wrap;
}
/* the closing CTA is a deep slab, not a card: it breaks the long light run
   from the price table down into the FAQ, and puts the amber button on its
   highest-contrast ground. .band--deep on the element swaps every ink with
   it, so the only override needed is bg (else it takes --deep-surface) and
   the border, which a slab defines by contrast rather than a hairline. */
.cta-band.band--deep{background:var(--deep-bg);border-color:transparent}
.cta-band h3{font-size:var(--fs-d4);margin-bottom:var(--s2);font-weight:800;color:var(--ink)}
.cta-band p{color:var(--ink-2);font-size:var(--fs-prose);max-width:var(--measure-n);font-weight:320}

/* ── 9 · faq ────────────────────────────────────────────────────────── */
.faq{padding-block:var(--sec)}
.faq__list{margin-top:var(--s8);border-top:1px solid var(--line)}
/* faq — grid-row accordion: exact height animation at any answer length,
   one open at a time, plus→× icon morph (no icon font, no SVG swap) */
.qa{border-bottom:1px solid var(--line-2)}
.qa__h{margin:0}
.qa__q{
  display:flex;align-items:center;justify-content:space-between;gap:var(--s5);width:100%;
  padding:var(--s5) 0;border:0;background:transparent;cursor:pointer;text-align:left;
  font-family:var(--f-disp);font-size:var(--fs-d6);font-weight:600;letter-spacing:-.018em;
  color:var(--ink);transition:color .2s;
}
.qa__q:hover{color:var(--accent-ink)}
/* offset only — colour comes from the global ring. 4px of clearance is kept
   so the ring does not sit on the neighbouring .qa hairline. */
.qa__q:focus-visible{outline-offset:4px}
.qa.is-open .qa__q{color:var(--accent-ink)}
.qa__q > span:first-child{flex:1}
.qa__icon{position:relative;width:13px;height:13px;flex:none}
.qa__icon::before,.qa__icon::after{
  content:"";position:absolute;top:50%;left:50%;width:13px;height:1px;background:var(--accent-ink);
  transform:translate(-50%,-50%) rotate(0deg);transition:transform .45s var(--ease);
}
.qa__icon::after{transform:translate(-50%,-50%) rotate(90deg)}
.qa.is-open .qa__icon::before{transform:translate(-50%,-50%) rotate(45deg)}
.qa.is-open .qa__icon::after{transform:translate(-50%,-50%) rotate(-45deg)}
.qa__a{display:grid;grid-template-rows:0fr;transition:grid-template-rows .45s var(--ease)}
.qa.is-open .qa__a{grid-template-rows:1fr}
.qa__in{overflow:hidden;min-height:0;max-width:var(--measure)}
.qa__in p{color:var(--ink-2);font-size:var(--fs-prose);font-weight:320;padding-bottom:var(--s5)}

/* ── 10 · footer (deep band — dusk) ─────────────────────────────────── */
.foot{padding-top:var(--s8)}
.foot__in{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.3fr);gap:clamp(32px,5vw,64px);padding-bottom:var(--s8)}
.foot__word{font-family:var(--f-disp);font-size:var(--fs-d5);font-weight:800;letter-spacing:-.03em;color:var(--ink)}
.foot__word span{color:var(--ink-2);font-weight:500}
.foot__slogan{font-family:var(--f-disp);font-size:var(--fs-d6);font-weight:600;letter-spacing:-.01em;color:var(--accent-ink);margin-top:var(--s2)}
.foot__tag{color:var(--ink-2);font-size:var(--fs-data);margin-top:var(--s3);max-width:var(--measure-n);font-weight:320}
/* asymmetric silhouette (footer-silhouette decision): Contact — the
   phone/email flap-window, the block visitors actually touch — spans
   both rows as the dominant panel. Where and Access compress into a
   narrow stack beside it, ruled off like a boarding-pass stub. Breaks
   the equal-column link-grid shape without moving any DOM/i18n. */
.foot__cols{display:grid;grid-template-columns:minmax(0,.7fr) minmax(0,1fr);grid-template-areas:"where contact" "access contact";gap:var(--s5)}
.foot__cols>div:nth-child(1){grid-area:where}
.foot__cols>div:nth-child(2){grid-area:contact;border-left:1px solid var(--line-2);padding-left:var(--s5)}
.foot__cols>div:nth-child(3){grid-area:access}
.foot__cols dt{font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.17em;text-transform:uppercase;color:var(--accent-ink);margin-bottom:var(--s3)}
.foot__cols dd{font-size:var(--fs-data);color:var(--ink-2);line-height:1.65;font-weight:320}
/* 14→16 is a rounding-rule EXCEPTION (up, not down): this is the gap between
   two adjacent ≥44px tap targets and must not tighten. */
.foot__tel{display:block;text-decoration:none;color:var(--ink-2);border:0!important;margin-bottom:var(--s4)}
.foot__tel span{display:block;width:max-content;font-family:var(--f-mono);font-size:var(--fs-data);letter-spacing:.02em;color:var(--ink);white-space:nowrap;border-bottom:1px solid var(--edge);padding-bottom:var(--s0);transition:color .2s,border-color .2s}
.foot__tel:hover span{color:var(--accent-ink);border-color:var(--accent-ink)}
.foot__coord{font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.09em;color:var(--ink-3);white-space:nowrap}

/* ── footer email — the VALUE rolls inside its own rule: address → prompt →
   confirmation, one flap per state. Deliberately wears .foot__tel's clothes
   (13px mono, 1px --edge underline, no fill, no radius) so it reads as a
   third contact line, not an imported widget. --edge, never --line: this
   rule outlines an interactive control.
   The address is carried on data-copy-email, never read from textContent,
   so a language switch can never change what lands on the clipboard. */
.foot__mail{cursor:pointer}
/* content-box is load-bearing: under the page's global border-box the 1px rule
   is taken OUT of the window, leaving 17.46px to show an 18.5px flap, and the
   descender of the g in gmail was being sliced off flat against the rule.
   Window height and flap line-height must stay equal — translateY(-100%) is
   relative to the flap's own height, so any drift misaligns every state.
   Matching 1.65 to .foot__cols dd keeps the value on the siblings' rhythm. */
.foot__mail span{box-sizing:content-box;height:1.65em;overflow:hidden;padding-bottom:0;
  border-bottom:1px solid var(--edge);letter-spacing:0}
.foot__mail b{display:block;font-weight:inherit;line-height:1.65;transition:transform .45s var(--ease)}
.foot__mail:hover b,.foot__mail:focus-visible b{transform:translateY(-100%)}
.foot__mail[data-copy="done"] b{transform:translateY(-200%)}
.foot__mail[data-copy="done"] span{color:var(--sea);border-color:var(--sea)}
/* focus ring comes from the house :where(a,…):focus-visible rule — no local one */
/* touch has no hover: the address must stay put until the tap resolves */
@media (hover:none){.foot__mail:hover b{transform:none}}
@media (prefers-reduced-motion:reduce){.foot__mail b{transition:none}}
.foot__plat{color:var(--ink-3)}
.foot__base{display:flex;justify-content:space-between;gap:var(--s5);flex-wrap:wrap;border-top:1px solid var(--line-2);padding-block:var(--s5);font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}

[data-placeholder]{opacity:.78}

/* ── footer under the page — content lifts away to reveal it (fx layer).
   Static by default; body.fx-foot (added by motion.js) switches the footer to
   fixed + spacer, so a script failure can never lose the footer. */
.foot-spacer{display:none;pointer-events:none}
body.fx-foot .page{position:relative;z-index:2;background:var(--sun-bg);box-shadow:0 34px 64px -20px rgba(7,26,33,.55)}
body.fx-foot .foot-spacer{display:block}
body.fx-foot .foot{position:fixed;left:0;right:0;bottom:0;z-index:1;margin:0}
.timeline__tick b{transition:color .3s}
.timeline__tick.is-past b{color:var(--accent-ink)}

/* ── map atmosphere — living bathymetric contours behind the chart ────── */
.map{position:relative;overflow:hidden}
.map__contours{position:absolute;inset:0;z-index:0;width:100%;height:100%;opacity:.6}
.map .wrap{position:relative;z-index:1}

/* ── reveal (clip-path wipes, not opacity fades) ──────────────────────
   Gated on .js-rv, added by the script only once it holds a live watcher.
   Nothing is ever hidden by CSS that JS might fail to undo. */
.js-rv [data-rv]{clip-path:inset(0 -50vw 100% -50vw);opacity:.001;will-change:clip-path}
.js-rv [data-rv].is-in{clip-path:inset(0 -50vw 0 -50vw);opacity:1;transition:clip-path .85s var(--ease),opacity .35s linear}

/* ── section rhythm ───────────────────────────────────────────────────
   MEASURED at 1440: --sec resolves to 144px and every band pads both
   ends with it, so a boundary between two sections is 288px of dead
   air with no band change to justify it. A boundary is ONE unit, not
   two: each section keeps its full top pad and gives up two-thirds of
   its bottom one. .faq is excluded because the footer follows it and
   needs the full pad. Resulting progression @1440:
     32 / 64 ....... inside a component (--s6 / --s8)
     96 ............ around the closing CTA band (--s9)
     144 ........... a section's own edge to its content (--sec)
     192 ........... between two sections (--sec + --sec-out)
   and the 288 disappears. */
.gap,.how,.sizes,.map,.go,.price{padding-bottom:var(--sec-out)}

/* ── SVG type floor ───────────────────────────────────────────────────
   SVG text scales with its viewBox, so a declared px is not a rendered
   px. Measured getScreenCTM().a: .szsvg is 1.633 desktop but .8 at
   ≤760, which would drop its annotations to sub-10px on a phone.
   (The .chart__* rules that lived here died with the SVG port plan —
   the live MapLibre map draws its own labels; see js/map.js.)        */
@media (max-width:760px){
  .szsvg__t{font-size:13.5px}                 /* × .8  = 10.8px rendered */
}

/* ── responsive ─────────────────────────────────────────────────────── */
@media (max-width:1080px){
  /* The hero photograph is a 1.791 panorama; a phone viewport is about 0.46.
     Cover-cropping it into a full-height field keeps only the middle quarter of
     the frame — empty sky above, empty water below, and the waterfront itself
     hidden behind the plate. So on a phone the photo becomes a deliberate band
     across the top at a size where the whole town still reads, and the plate
     docks into its lower edge instead of floating on a crop of nothing.
     46svh, not 50: at 360x740 a 50svh band pushed "Open a locker" 20px past the
     fold. 46 keeps both hero buttons above it on the smallest phone we support
     and costs about 30px of sky nobody was reading. */
  .hero__in{grid-template-columns:1fr;gap:var(--s7);padding-top:calc(46svh - 96px)}
  .hero{min-height:auto;padding-top:0}
  .hero__field{bottom:auto;height:46svh}
  /* the band has to END somewhere, and a hard cut against the limestone shows
     in the plate's side gutters — so it dissolves over its last fifth instead */
  .hero__field img{
    object-position:50% 60%;
    -webkit-mask-image:linear-gradient(180deg,#000 0 78%,transparent 100%);
            mask-image:linear-gradient(180deg,#000 0 78%,transparent 100%);
  }
  /* the desktop wash lands the photo into the limestone at the bottom; here the
     band's own mask does that, so this only has to keep the nav legible */
  .hero__field::after{
    background:linear-gradient(180deg,
      rgba(238,242,241,.90) 0%,rgba(238,242,241,.28) 15%,
      rgba(238,242,241,0) 36%,rgba(238,242,241,0) 100%);
  }
  .board{max-width:560px}
  .gap__grid,.map__grid{grid-template-columns:1fr}
  .price__head{grid-template-columns:1fr;align-items:start;gap:var(--s5)}
  .story{grid-template-columns:1fr}
  .media-col{display:none}
  .step{min-height:0;padding:var(--s6) 0}
  .step__figure{display:block}
  .assure{column-gap:var(--s4)}
  .assure__n,.assure__body{padding-block:var(--s5) var(--s4)}
  .strip__in{grid-template-columns:repeat(2,1fr)}
  .strip__in li:nth-child(3){border-left:0;padding-left:0}
  .strip__in li:nth-child(n+3){border-top:1px solid var(--line-2)}
  /* ── mobile wayfinding ────────────────────────────────────────────────
     The same five <a> nodes, re-laid as departure-board rows in a dark
     signage panel under the rail. Dark is legitimate here for the same
     reason the board is: it is an instrument, not a band. No duplicate DOM,
     so i18n and the smooth-scroll handlers in site.js need no changes, and
     the BOOK action is left to .ctabar rather than repeated. */
  .nav__links::before{display:none}
  .nav__links{
    display:none;
    position:absolute;left:0;right:0;top:100%;
    flex-direction:column;gap:0;
    background:var(--deep-bg);
    border-top:1px solid rgba(237,241,240,.13);
    box-shadow:0 34px 80px -28px rgba(6,28,35,.75);
    padding:var(--s3) var(--pad) var(--s5);
    counter-reset:navi;
    text-transform:uppercase;
  }
  .nav.is-open .nav__links{display:flex}
  .nav__links a{
    counter-increment:navi;
    display:flex;align-items:baseline;gap:14px;
    min-height:44px;padding:14px 0;
    color:var(--deep-ink);
    border-bottom:1px solid rgba(237,241,240,.075);
  }
  .nav__links a:last-child{border-bottom:0}
  .nav__links a::before{content:"0" counter(navi);color:var(--deep-ink-2);font-size:var(--fs-label);letter-spacing:.2em;flex:none}
  .nav__links a::after{display:none}
  .nav__links a:hover{color:var(--amber)}

  /* the toggle IS the C1 mark: two door tiles and the code-dot. Open splits
     the hinge gap. Not a hamburger — three bars would be the template. */
  .nav__door{
    display:inline-flex;align-items:center;gap:9px;
    min-height:44px;padding:6px 11px;cursor:pointer;
    background:none;border:1px solid var(--edge);color:var(--sun-ink-2);
    font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.1em;
  }
  .nav__door-m{position:relative;display:block;width:15px;height:19px;flex:none}
  .nav__door-m i{position:absolute;left:0;right:0;height:8px;background:currentColor;transition:top .28s var(--ease),bottom .28s var(--ease)}
  .nav__door-m i:first-of-type{top:0}
  .nav__door-m i:last-of-type{bottom:0}
  .nav__door-m b{position:absolute;right:2px;bottom:2px;width:3px;height:3px;border-radius:50%;background:var(--amber)}
  .nav__door-t{white-space:nowrap}
  .nav.is-open .nav__door{border-color:var(--sun-ink);color:var(--sun-ink)}
  .nav.is-open .nav__door-m i:first-of-type{top:-3px}
  .nav.is-open .nav__door-m i:last-of-type{bottom:-3px}

  .foot__in{grid-template-columns:1fr}
}
@media (max-width:760px){
  :root{--sec:clamp(64px,13vw,96px);--fs-data:15.5px}
  .hero__scroll{display:none}
  .hero__plate{padding:var(--s5)}
  .sizecard-row{grid-template-columns:1fr}
  .sizecard{flex-direction:row;align-items:center;gap:var(--s5)}
  .sizecard__viz{flex:0 0 96px}
  .szsvg{max-width:96px}
  .sizecard__meta{flex:1}
  .slide{width:min(78vw,470px)}
  .slide__cap .place__rose{width:88px;height:66px;flex-basis:88px}
  .strip__in{grid-template-columns:1fr}
  .strip__in li{padding:var(--s5) 0}
  .strip__in li + li{border-left:0;padding-left:0;border-top:1px solid var(--line-2)}
  .foot__cols{grid-template-columns:1fr;grid-template-areas:none;gap:var(--s5)}
  /* grid-area:auto is load-bearing: without it the named areas from the
     desktop rule survive into the 1-column grid and stack all three blocks
     into the same implicit cell (verified overprint at 500px). :nth-child
     is needed to out-rank the desktop assignments' specificity. */
  .foot__cols>div:nth-child(1),.foot__cols>div:nth-child(2),.foot__cols>div:nth-child(3){grid-area:auto}
  .foot__cols>div:nth-child(2){border-left:0;padding-left:0;border-top:1px solid var(--line-2)}
  .nav__cta{display:none}
  .timeline__track{margin:var(--s7) 0 var(--s8)}
  /* spans count from .timeline__fill: (2)=11:00 (3)=13:00 (4)=17:00 (5)=18:00 —
     keep the endpoints, hide the middle two, pin the endpoints to the track edges */
  .timeline__tick:nth-of-type(3),.timeline__tick:nth-of-type(4){opacity:0}
  .timeline__tick:nth-of-type(2) i,.timeline__tick:nth-of-type(2) b{left:0;translate:0 0;text-align:left}
  .cta-band{flex-direction:column;align-items:flex-start}
}
/* ── 1081–1200: the Greek rail ────────────────────────────────────────
   Greek is the only language whose links do not fit here. Measured at 1081px
   they need 398.8px and the row offers 361.4, so "ΠΩΣ ΛΕΙΤΟΥΡΓΕΙ" broke onto
   a second line and doubled the nav's height. This predates the switcher and
   was worse before it: with the four-code rail English wrapped at 1081 too,
   and Greek was 97.6px short rather than 37.4px.

   Tightening the two rail gaps returns 48px — 16 from the three-column gap
   (2 × 8) and 32 from the four gaps between five links (4 × 8) — clearing the
   37.4px shortfall with 10.6px spare. Gaps, not type: nothing is made smaller
   or harder to read, and above 1200px the roomier spacing is untouched. */
@media (min-width:1081px) and (max-width:1200px){
  .nav__in{gap:var(--s5)}
  .nav__links{gap:var(--s4)}
  /* the docking hairline is offset by half the rail gap — it has to follow it */
  .nav__links::before{left:calc(var(--s5) / -2)}
}

/* ── nav rail width ladder ────────────────────────────────────────────
   Rewritten with the switcher. The old ladder squeezed the four-code rail's
   padding in three steps (9px → 6px → 5px) purely to keep the door button on
   screen; the rail was 186.6px and the row overflowed a 450px content box by
   53px at 500px wide. One trigger is ~78px, so 108px came back and two of
   the three steps are simply unnecessary. Re-measured below, not inherited. */
@media (max-width:480px){
  .brand{font-size:15px}
  .nav__in{gap:var(--s4)}
  .nav__door-n{display:none}
}
@media (max-width:400px){
  /* the code is redundant next to the flag once space is this tight, and the
     flag is the half a non-English speaker actually reads. The panel still
     names every language in full, so nothing is lost — only repeated. */
  .langsw__code{display:none}
}
@media (max-width:360px){
  .brand__place{display:none}
}

/* ── mobile CTA bar — the phone's only action once the hero is gone ──── */
.ctabar{
  position:fixed;left:0;right:0;bottom:0;z-index:90;
  display:flex;align-items:center;justify-content:space-between;gap:var(--s4);
  background:var(--bg);border-top:1px solid var(--line-2);
  padding:var(--s2) var(--pad) calc(var(--s2) + env(safe-area-inset-bottom));
  transform:translateY(102%);transition:transform .35s var(--ease);
}
.ctabar.is-up{transform:translateY(0)}
.ctabar__hint{font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.05em;color:var(--ink-2)}
/* the third button size is gone — the bar now uses the compact .btn spec
   unmodified. white-space:nowrap is already on .btn. */
@media (min-width:761px){.ctabar{display:none}}

/* ── reduced motion ─────────────────────────────────────────────────── */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
  .js-rv [data-rv]{clip-path:none;opacity:1}
  .boot{display:none}
  .hero__scroll{display:none}
  .timeline__fill{transform:scaleX(1)}
  /* scrollytelling flattens to a plain article; reel becomes a native scroller */
  .story{grid-template-columns:1fr}
  .media-col{display:none}
  .step{min-height:0;padding:var(--s6) 0}
  .step__figure{display:block}
  .step__n{color:var(--accent-ink)}
  .reel{overflow-x:auto;cursor:auto}
  .slide{transform:none}
  .slide__cap{transform:none}
  .nav.is-away{transform:none}
}
@media (prefers-reduced-motion:reduce) and (min-width:1081px){
  .step{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);column-gap:clamp(28px,5vw,72px);align-items:start}
  .step__n,.step__h,.step__p{grid-column:1}
  .step__figure{grid-column:2;grid-row:1/4;margin:0;max-width:none}
}
