/* ══════════════════════════════════════════════════════════════════════
   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);
  /* floor 96, not 72: the ≤760.98px override tops out at 96px (13vw clamped),
     and the old 72px floor let this fluid value sink to ~76px right above
     that breakpoint — a wider viewport getting LESS section rhythm than a
     narrower one. 96 makes the wide side pick up exactly where mobile caps. */
  --sec:clamp(96px,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);
  /* 2.9, not 2.7: at the same coefficient as --fs-d4 the two clamps compute
     byte-identical across 1037–1310px (both mid-ramp, same slope) even though
     their min/max bounds differ. A steeper slope keeps d3 strictly above d4
     at every width instead of only at the endpoints. */
  --fs-d3    :clamp(28px,2.9vw,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);

  /* the one dark-panel drop-shadow, shared by the three deep-ground panels
     that float over a lighter section (lang menu, board, mobile nav sheet) */
  --shadow-panel:0 34px 80px -28px rgba(6,28,35,.75);
}

/* ── 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)}
.btn--ghost:active{background:rgba(10,31,38,.08)}
.band--deep .btn--ghost:hover{background:rgba(237,241,240,.06)}
.band--deep .btn--ghost:active{background:rgba(237,241,240,.1)}

/* ── 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);
  /* --edge is only 2.70:1 here — this is the one control that sits directly
     on the hero sky (#B0E0F0), not on a sun surface. #5E7681 clears 3.37:1
     against the sky and stays ≥3.9 on every sun surface too. */
  background:none;border:1px solid #5E7681;color:var(--sun-ink-2);cursor:pointer;
  font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.1em;
  padding:var(--s2) var(--s3);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:calc(var(--s2) * -1) calc(var(--s1) * -1)}
.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% + var(--s3));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:var(--shadow-panel);
}
.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:calc(var(--s3) * -1);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:calc(var(--s2) * -1);bottom:calc(var(--s2) * -1);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)}
/* 2px/.6, not 1px/.2: at ~1.45:1 over the bright sea photo the old hairline
   track was practically invisible — the cue needs real weight, not opacity. */
.hero__scroll{position:absolute;left:50%;bottom:22px;translate:-50% 0;width:2px;height:44px;background:rgba(10,31,38,.6);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:var(--shadow-panel), 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}

/* the numeral column (.assure__n) is gone from the markup — one column now,
   so .assure__body's own border-bottom is the full-width row rule and needs
   no column-gap to notch it, matching the continuous border-top above */
.assure{display:grid;grid-template-columns:minmax(0,1fr);margin-top:var(--s8);border-top:1px solid var(--line)}
.assure__item{display:contents}
.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}
/* a steel locker door is not water — sea-teal was doing decorative-UI work
   outside the brand's colour rules. Both cards now fill neutral; the hero
   card keeps its amber accent on the stroke and code only. */
.szsvg__box{fill:color-mix(in srgb,var(--ink-3) 8%,transparent);stroke:var(--ink-3);stroke-width:1.6}
.sizecard--hero .szsvg__box{fill:color-mix(in srgb,var(--ink-3) 8%,transparent);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:760.98px){.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:var(--s3);top:var(--s3);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:var(--s3) var(--s4);cursor:pointer;line-height:1.2;
  min-height:44px;transition:background .2s var(--ease),border-color .2s 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:var(--s2);top:var(--s2);padding:var(--s2) var(--s3);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:var(--fs-label);color:#5A6E76}
.portmap .maplibregl-ctrl.maplibregl-ctrl-attrib a{color:#3C4F57}
.portmap .maplibregl-cooperative-gesture-screen{background:rgba(11,32,39,.35);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:var(--fs-label);letter-spacing:.11em;color:var(--amber);background:rgba(11,32,39,.88);border:1px solid rgba(240,166,60,.5);border-radius:2px;padding:var(--s2) var(--s3) var(--s2);white-space:nowrap}
/* 9.5px was under the file's 11px floor — raised to --fs-label */
.pmk__sub{display:block;font-size:var(--fs-label);letter-spacing:.09em;color:var(--deep-ink-2);margin-top:var(--s1)}
/* 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:760.98px){.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:var(--s2) var(--s2) var(--s1)}
}
@media (max-width:400px){
  .pmk__card{font-size:var(--fs-label);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}
/* radius 10, not 4 — concentric with the pin's own 2px radius plus the 8px inset */
.pmk__pin::before{content:"";position:absolute;inset:calc(var(--s2) * -1);border:1px solid rgba(240,166,60,.45);border-radius:10px;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,transparent,#000 var(--s7),#000 calc(100% - var(--s7)),transparent);-webkit-mask-image:linear-gradient(90deg,transparent,#000 var(--s7),#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}
/* --edge, not --line: --line resolves to 1.4:1 on --sun-bg, too weak to read
   as a card edge. --edge is the documented 3.40:1 boundary token. */
.slide{flex:0 0 auto;width:clamp(280px,31vw,470px);margin:0;background:var(--surface);border:1px solid var(--edge);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{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}
/* was 7 user units (4.55px/3.85px rendered) with display:none — invisible.
   10u × 0.65/0.55 = 6.5px/5.5px, still short of the 11px floor, but the file's
   own overflow ceiling caps this at <15u (the "N" glyph clips the viewBox top
   above that) without repositioning the markup — 10 is the safe maximum this
   ceiling allows. The needle + the SVG aria-label still carry the bearing. */
.rose__card{font-family:var(--f-mono);font-size:10px;fill:var(--ink-3);letter-spacing:.02em}
.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)}
/* --fs-d6 fit a single "!" glyph; "+1 H" is a 4-char mono string and needs to
   sit at a prose size, not a display one, to keep its width proportionate */
.warn__k{font-family:var(--f-mono);color:var(--accent-ink);font-size:var(--fs-prose);letter-spacing:.02em;white-space:nowrap;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:760.98px){
  .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);
  }
  /* no mask here: it was clipping the last digit of the M-column price at
     390px (worse at 320px) on load, before any swipe happened. The "Swipe →"
     hint plus the naturally cut-off L column are the scroll affordance. */
  .swipe + .tbl-scroll{margin-top:var(--s5)}
}
.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)}

/* ≤360px: the "the usual gap" tag was the single widest thing in the
   Duration column (126px), pushing the M column's price entirely off the
   320px viewport on load, not just its last digit. Tightening the tag and
   the cell gutters brings the M price back on screen without touching type
   floors. */
/* 440, not 360: the inline tag row was tuned against the EN "the usual gap" —
   FR "le créneau habituel" runs 60px wider and pushed the M price off-screen
   at 390 (measured). Below 440 every language drops the tag onto its own line. */
@media (max-width:440px){
  .rates .tag{display:block;width:max-content;margin-left:0;margin-top:var(--s1);translate:0}
}
@media (max-width:360px){
  .rates th,.rates td{padding-right:var(--s2)}
  .rates tbody th{letter-spacing:0;white-space:normal}
}

.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;
}
/* --ink + underline, not --accent-ink: that colour is reserved for .is-open,
   so a hovering-but-closed question must not read as already answered */
.qa__q:hover{color:var(--ink);text-decoration:underline;text-underline-offset:.2em}
/* 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)}
/* the Call anchor is label-only (its number lives once, on the WhatsApp row
   above) — without a number line it collapsed to 26px, under the 44px tap
   floor the comment above defends. Flex + min-height restores the target. */
.foot__call{display:flex;align-items:center;min-height:44px}
/* .foot__lbl carries no rule of its own — a plain inline span inherits the
   anchor's own color/font exactly as the old bare text node did. */
.foot__tel .foot__num{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 .foot__num{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 .foot__num{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%)}
/* --accent-ink, not --sea: sea-teal was doing copy-success state work here
   with no relation to the sea motif — the footer's own accent already means
   "success/active" everywhere else (langsw, faq is-open) */
.foot__mail[data-copy="done"] .foot__num{color:var(--accent-ink);border-color:var(--accent-ink)}
/* 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)}
/* the border used to sit on the .wrap box itself, so it painted 56px wider
   each side than every other hairline (the wrap's own padding-inline). A
   ::before inset by that same --pad keeps its x-extent matching the rest. */
.foot__base{position:relative;display:flex;justify-content:space-between;gap:var(--s5);flex-wrap:wrap;padding-block:var(--s5);font-family:var(--f-mono);font-size:var(--fs-label);letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}
.foot__base::before{content:"";position:absolute;left:var(--pad);right:var(--pad);top:0;height:1px;background:var(--line-2)}

[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:760.98px){
  .szsvg__t{font-size:13.5px}                 /* × .8  = 10.8px rendered */
}

/* ── responsive ─────────────────────────────────────────────────────── */
/* .98 on every max-width paired with a min-width one step up (761px/1081px):
   at exactly 761/1081 an integer max-width:760px/1080px and the min-width
   query both fail to match, so neither side's rules apply — the .98 closes
   that hole without moving where either breakpoint visually lands. */
@media (max-width:1080.98px){
  /* 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__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:var(--shadow-panel);
    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:var(--s4);
    min-height:44px;padding:var(--s4) 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:var(--s2);
    min-height:44px;padding:var(--s2) var(--s3);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:760.98px){
  :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}
}
/* the ≤760.98 override bumps --fs-data to 15.5px for phone legibility; the
   root static value is 13.5px. Between the two breakpoints that is a wider
   viewport getting SMALLER data type than a narrower one — bridge the tablet
   band up to the next real breakpoint so it never dips below the mobile
   value before 1080.98px takes over. */
@media (min-width:761px) and (max-width:1080.98px){
  :root{--fs-data:15.5px}
}
/* ── 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}
  .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}
}
