/* ============================================================================
   RIBARSKO SELO  ·  V6 "SREBRO"  ·  shared foundation
   Doctrine: _tools/V6-DOCTRINE.md. Read it before changing anything here.

   The catch is silver. The site is silver on ink.

   Everything from V1 to V5 is gone: the navy midnight palette, the ivory
   chapter grounds, candle gold and the ten per-page accents, Piazzolla and
   Golos, the arch-topped photographs, the ruled full-width entry register,
   the hairline caps buttons, the cursor dot, the progress hairline.

   Rules that this file enforces and that must not be undone:
     - no border-radius anywhere in the site
     - img{height:auto}, because width/height attributes otherwise kill
       CSS aspect-ratio
     - never a zero-area style on a [data-rv] element: clip a CHILD
     - reduced motion lands on the FINISHED state, never a disabled one
   ========================================================================== */

/* ------------------------------------------------------------------ tokens */

:root {
  /* grounds: four near-blacks, all achromatic-cold */
  --ink:    #08090B;
  --slate:  #101317;
  --stone:  #181C21;
  --pitch:  #000000;

  /* light */
  --lume:   #F3F1EC;
  --lume-2: rgba(243, 241, 236, .66);
  --lume-3: rgba(243, 241, 236, .42);
  --hair:   rgba(243, 241, 236, .14);
  --hair-2: rgba(243, 241, 236, .07);

  /* the one metal, five jobs, never a fill */
  --ag:     #A9AFB2;
  --ag-dim: rgba(169, 175, 178, .38);

  /* the shell writes --accent per page; in V6 it always resolves to the metal */
  --accent: var(--ag);

  /* type */
  /* The client's own faces, from Fontshare / Indian Type Foundry.
     Both are Latin only; fonts.css attaches their Cyrillic companions under the
     same family names by unicode-range, so the switch is invisible.
     Melodrama has no italic: the <em> clauses resolve to Cormorant italic. */
  --serif: 'Melodrama', 'Disp Fallback', Georgia, 'Times New Roman', serif;
  --sans:  'General Sans', 'UI Fallback', system-ui, -apple-system, Arial, sans-serif;
  /* There is no monospace on this site any more. A coder's mono in a header is
     the single loudest "built by a machine" signal a luxury page can send, and
     it was the first thing the client named. --mono survives as a NAME because
     a dozen page stylesheets reference it; it resolves to the text face with
     tabular figures, which aligns a column of coordinates just as well and
     reads like a specimen label instead of a terminal. */
  --mono:  var(--sans);

  /* display scale, multiplied per language: Cyrillic sets far wider */
  --disp-k: 1;
  --t-mega: calc(clamp(3.3rem, 11.4vw, 12.6rem) * var(--disp-k));
  --t-h1:   calc(clamp(2.5rem, 6.6vw, 6.2rem)   * var(--disp-k));
  --t-h2:   calc(clamp(1.95rem, 4.2vw, 3.9rem)  * var(--disp-k));
  --t-h3:   calc(clamp(1.35rem, 1.95vw, 1.85rem) * var(--disp-k));

  /* rhythm */
  --pad:  clamp(104px, 13vh, 190px);
  --gut:  clamp(20px, 5vw, 96px);
  --hd-h: 78px;

  /* the inset of anything that floats in the bottom corner: the WhatsApp dock
     and the cookie notice. One token so the two can never disagree. */
  --corner: clamp(16px, 2.2vw, 30px);

  --ease: cubic-bezier(.16, .72, .24, 1);
}

/* Russian display copy is measured, not guessed: Old Standard TT Cyrillic sets
   about 1.5x the width of the same sentence in Latin, so a headline tuned at
   1440 for CG runs an extra line and overflows in RU at the same value. */
html[lang="ru"] { --disp-k: .92; }
html[lang="ru"] h1, html[lang="ru"] h2, html[lang="ru"] h3 { letter-spacing: -.004em; }


/* ------------------------------------------------------- legacy token bridge
   The page stylesheets that have not been hand-composed for V6 yet are almost
   entirely token driven: between 65 and 152 var() references each, and single
   digit hardcoded colours. Aliasing the V5 names onto the V6 palette moves
   those pages into the SREBRO world in one step, keeping the layout work that
   was already good and replacing exactly what the client rejected: the navy
   and ivory grounds, the candle gold, the ten room accents.

   These are a bridge, not a vocabulary. Nothing written from here on may use
   them, and each one goes as its page is composed. */
:root {
  /* grounds */
  --abyss: var(--ink);
  --navy: var(--slate);
  --navy-soft: var(--stone);
  --navy-lift: var(--stone);
  --night: var(--ink);
  --cave: var(--pitch);
  --ink-2: var(--ink);
  /* the ivory day chapters are dead: they resolve to near-black */
  --ivory: var(--slate);
  --ivory-warm: var(--stone);
  --ivory-deep: var(--ink);
  --warm: var(--stone);
  --tint: transparent;
  /* light */
  --pearl: var(--lume);
  --pearl-dim: var(--lume-2);
  --pearl-faint: var(--lume-3);
  --pearl-ghost: rgba(243, 241, 236, .14);
  /* the accent is the one metal, everywhere, on every page */
  --accent-full: var(--ag);
  --accent-dim: var(--ag-dim);
  --accent-day: var(--ag);
  --accent-day-em: var(--ag);
  --gold: var(--ag);
  --brass: var(--ag);
  --glow: rgba(169, 175, 178, .18);
  --draw: var(--ag);
  --plan: var(--hair);
  --plan-soft: var(--hair-2);
  --rail: var(--hair);
  --scrim: rgba(8, 9, 11, .72);
  --veil: rgba(8, 9, 11, .58);
  --cast: rgba(8, 9, 11, .5);
  --lum: 1;
  --lhr: var(--hair);
  --lv: var(--lume-2);
  /* type */
  --disp: var(--serif);
  --gar: var(--serif);
  /* rhythm */
  --s2: 8px;  --s3: 14px; --s4: 22px; --s5: 34px;
  --s6: 52px; --s7: 78px; --s8: 112px; --s9: 156px;
  --head-h: var(--hd-h);
  --ease-out: var(--ease);
  --measure: 66ch;
  --lad-pad: clamp(20px, 3vw, 44px);
  /* shadows are dead: offset ink shadows were a named rejection */
  --sha: none; --shb: none; --shx: 0px; --shy: 0px;
}

/* The grain. Every dark gradient over a photograph on this site carries it:
   an 8 bit gradient from near-black to transparent BANDS on a real screen, and
   those bands are what read as cheap. Grain dithers them away, and it is what
   printed photography has always done. */
:root {
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
}

/* ------------------------------------------------------------------- reset */

*, *::before, *::after { box-sizing: border-box; }

html {
  background: var(--ink);
  color: var(--lume);
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scrollbar-color: rgba(243, 241, 236, .2) var(--ink);
}

/* the ambience: one fixed, very slow luminance drift on its own clock.
   Autonomous, so it is composed at every scroll position by construction. */
html::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(128% 70% at 16% -12%, rgba(169, 175, 178, .075), transparent 62%),
    radial-gradient(96% 58% at 94% 6%, rgba(169, 175, 178, .04), transparent 60%);
  animation: rs-breath 21s ease-in-out infinite;
}
@keyframes rs-breath {
  0%, 100% { opacity: .72; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.06); }
}

html.rs-lock { overflow: hidden; }

body {
  margin: 0;
  font-family: var(--sans);
  font-variant-numeric: tabular-nums;
  font-weight: 300;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--lume-2);
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, video, svg { display: block; max-width: 100%; }
/* width/height attributes on <img> disable CSS aspect-ratio without this */
img, video { height: auto; }

a { color: inherit; text-decoration: none; }

button, input, select, textarea {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  margin: 0;
}
button { cursor: pointer; }

figure { margin: 0; }
ul, ol { list-style: none; margin: 0; padding: 0; }
p { margin: 0; }
dl, dd, dt { margin: 0; }

::selection { background: var(--lume); color: var(--ink); }

:focus-visible {
  outline: 1px solid var(--ag);
  outline-offset: 3px;
}

::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: var(--ink); }
::-webkit-scrollbar-thumb { background: rgba(243, 241, 236, .18); }
::-webkit-scrollbar-thumb:hover { background: rgba(243, 241, 236, .3); }

.skip {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 200;
  transform: translateY(-180%);
  background: var(--lume);
  color: var(--ink);
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: .7em 1.1em;
  transition: transform .3s var(--ease);
}
.skip:focus { transform: none; }

/* --------------------------------------------------------------- structure */

main { padding-top: var(--hd-h); }

.shell {
  width: 100%;
  max-width: 1560px;
  margin-inline: auto;
  padding-inline: var(--gut);
}
.shell--tight { max-width: 1120px; }
.shell--mid   { max-width: 1320px; }
.shell--full  { max-width: none; padding-inline: 0; }

.sec {
  position: relative;
  padding-block: var(--pad);
}
.sec--air    { --pad: clamp(150px, 23vh, 300px); }
.sec--dense  { --pad: clamp(64px, 8vh, 110px); }
.sec--flush  { --pad: 0px; }
.sec--top0   { padding-top: 0; }
.sec--bot0   { padding-bottom: 0; }

/* grounds. Sections with no ground modifier are transparent so the ambience
   shows through: that is where the rhythm comes from now, not colour swaps. */
.gnd-slate { background: var(--slate); }
.gnd-stone { background: var(--stone); }
.gnd-pitch { background: var(--pitch); }
.gnd-ink   { background: var(--ink); }

/* a section can carry a hairline as its own edge */
.edge-t { border-top: 1px solid var(--hair-2); }
.edge-b { border-bottom: 1px solid var(--hair-2); }

/* the opening: a full-bleed hero pulls up under the fixed header */
.opening { margin-top: calc(var(--hd-h) * -1); }

/* -------------------------------------------------------------------- type */

h1, h2, h3, h4 {
  font-family: var(--serif);
  font-weight: 380;
  line-height: 1.02;
  letter-spacing: -.008em;
  color: var(--lume);
  margin: 0;
  text-wrap: balance;
}
h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); line-height: 1.14; letter-spacing: -.006em; }
h4 { font-size: 1.06rem; line-height: 1.3; }

/* the one headline that IS the page */
.mega {
  font-size: var(--t-mega);
  font-weight: 380;
  /* Melodrama carries tall ascenders and a deep comma, so at .92 two lines read
     as two separate statements with a gap between them. At .84 the lines lock
     into one block, which is what a display headline this size is for. Do not
     go under .80: the comma of line one starts to touch the ascenders below. */
  line-height: .84;
  /* Melodrama is a wide, high-contrast display face and it wants air, not a
     squeeze: the negative tracking Cormorant needed closes its counters up. */
  letter-spacing: -.012em;
}

/* Uppercase serif display is banned. Caps live in the mono and the sans. */
/* Melodrama ships no italic, so an <em> clause is BOSKA italic. Boska sets
   fuller and slightly larger on the same body than Melodrama, so the clause
   comes back to 1em and loses a little weight; otherwise the italic reads
   bolder than the roman it is meant to sit inside. */
h1 em, h2 em, h3 em, .mega em {
  font-style: italic;
  font-weight: 300;
  font-size: .96em;
  letter-spacing: -.002em;
  color: inherit;
}

.lede {
  font-family: var(--sans);
  font-weight: 250;
  font-size: clamp(1.12rem, 1rem + .66vw, 1.48rem);
  line-height: 1.46;
  color: var(--lume);
  max-width: 54ch;
}

.prose {
  font-family: var(--sans);
  font-weight: 300;
  font-size: clamp(1rem, .94rem + .3vw, 1.17rem);
  line-height: 1.64;
  color: var(--lume-2);
  max-width: 66ch;
}
.prose > * + * { margin-top: 1.1em; }
.prose strong, .prose b { font-weight: 500; color: var(--lume); }
.prose em { font-family: var(--serif); font-style: italic; font-size: 1.09em; color: var(--lume); }
.prose a { color: var(--lume); box-shadow: inset 0 -1px 0 var(--ag-dim); transition: box-shadow .35s; }
.prose a:hover { box-shadow: inset 0 -1px 0 var(--ag); }

.note {
  font-family: var(--sans);
  font-weight: 300;
  font-size: .89rem;
  line-height: 1.55;
  color: var(--lume-3);
  max-width: 58ch;
}

/* mono: labels, figures, coordinates, everything countable */
/* THE LABEL REGISTER.
   Small letterspaced caps in the display serif. This is the register a printed
   brochure uses for a caption or a plate, and it is the thing the uppercase
   mono was standing in for. */
.mono {
  font-family: var(--serif);
  font-weight: 400;
  font-size: .78rem;
  letter-spacing: .19em;
  text-transform: uppercase;
  color: var(--lume-3);
  line-height: 1.5;
  font-variant-numeric: lining-nums tabular-nums;
}
.mono--ag { color: var(--ag); }
.mono--lume { color: var(--lume); }

.fig {
  font-family: var(--sans);
  font-weight: 350;
  font-variant-numeric: lining-nums tabular-nums;
  letter-spacing: .03em;
  color: var(--ag);
}

/* --------------------------------------------------------- chapter opener */
/* No letterspaced-caps kicker over a hairline anywhere. A chapter opens as a
   margin column carrying a mono index and the section word, and a wide column
   carrying the display headline. The hairline is vertical, in the gutter. */

.chap {
  display: grid;
  grid-template-columns: minmax(112px, 200px) minmax(0, 1fr);
  gap: clamp(22px, 3.6vw, 66px);
  align-items: start;
}
.chap-m {
  position: relative;
  padding-top: .5em;
  padding-right: clamp(11px, 1.8vw, 33px);
  border-right: 1px solid var(--hair);
  display: grid;
  gap: .5em;
  justify-items: start;
}
.chap-no {
  font-family: var(--serif);
  font-style: italic;
  font-size: .95rem;
  letter-spacing: .04em;
  color: var(--ag);
  font-variant-numeric: lining-nums;
}
.chap-w {
  font-family: var(--serif);
  font-size: .78rem;
  letter-spacing: .19em;
  text-transform: uppercase;
  color: var(--lume-3);
  line-height: 1.5;
}
.chap-b { min-width: 0; }
.chap-b > h2, .chap-b > h1 { max-width: 20ch; }
.chap-b > * + * { margin-top: clamp(18px, 2.4vw, 34px); }

/* Anything that belongs to a chapter but is not inside it, a ledger or a plate,
   lines up with the headline instead of the page edge. */
.chap-align {
  display: grid;
  grid-template-columns: minmax(112px, 200px) minmax(0, 1fr);
  gap: clamp(22px, 3.6vw, 66px);
}
.chap-align > * { grid-column: 2; }

@media (max-width: 860px) {
  .chap-align { grid-template-columns: 1fr; }
  .chap-align > * { grid-column: 1; }
  .chap { grid-template-columns: 1fr; gap: 20px; }
  .chap-m {
    border-right: 0;
    border-bottom: 1px solid var(--hair);
    padding: 0 0 12px;
    grid-auto-flow: column;
    justify-content: start;
    gap: 1.4em;
    align-items: baseline;
  }
}

/* ------------------------------------------------------------- the plate */
/* Replaces the old full-width ruled entry line. Narrow, left-hairlined, mono,
   never boxed, never centred, sits in a void. Carries the address data that
   every page must state. */

.plate {
  border-left: 1px solid var(--hair);
  padding-left: clamp(16px, 1.8vw, 26px);
  display: grid;
  gap: .5em;
  max-width: 560px;
  font-family: var(--sans);
  font-weight: 300;
  font-size: .82rem;
  line-height: 1.6;
  font-variant-numeric: lining-nums tabular-nums;
}
.plate-no {
  font-family: var(--serif);
  font-style: italic;
  font-size: .92rem;
  letter-spacing: .05em;
  color: var(--ag);
}
.plate-name {
  font-family: var(--serif);
  font-size: .84rem;
  letter-spacing: .19em;
  text-transform: uppercase;
  color: var(--lume);
  padding-bottom: .45em;
}
.plate-r {
  display: grid;
  grid-template-columns: minmax(96px, 27%) minmax(0, 1fr);
  gap: .1em 1.1em;
}
.plate-k {
  font-family: var(--serif);
  font-size: .72rem;
  color: var(--lume-3);
  letter-spacing: .17em;
  text-transform: uppercase;
  padding-top: .12em;
}
.plate-v { color: var(--lume-2); }
.plate-v a { color: var(--lume); box-shadow: inset 0 -1px 0 var(--ag-dim); transition: box-shadow .3s; }
.plate-v a:hover { box-shadow: inset 0 -1px 0 var(--ag); }
.plate-v i { font-style: normal; color: var(--lume-3); }
.plate .fig { color: var(--ag); }
.plate-soft { color: var(--lume-3); }

@media (max-width: 560px) {
  .plate-r { grid-template-columns: 1fr; }
  .plate-r + .plate-r { margin-top: .5em; }
}

/* --------------------------------------------------------------- actions */
/* Primary is a solid bone block. Secondary is text with a drawn underline.
   Hairline-outlined letterspaced caps buttons with sweep fills are dead. */

.act {
  display: inline-flex;
  align-items: center;
  gap: .7em;
  background: var(--lume);
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 500;
  font-size: .9rem;
  letter-spacing: .005em;
  line-height: 1;
  padding: 1.05em 1.6em;
  transition: transform .4s var(--ease), background .4s;
}
.act:hover { transform: translateY(-2px); background: #FFFDF8; }
.act:active { transform: none; }

.act--ghost {
  background: none;
  color: var(--lume);
  box-shadow: inset 0 0 0 1px var(--hair);
}
.act--ghost:hover { background: none; box-shadow: inset 0 0 0 1px var(--ag); }

.link {
  position: relative;
  display: inline-block;
  font-family: var(--sans);
  font-weight: 400;
  font-size: .93rem;
  color: var(--lume);
  padding-bottom: .3em;
}
.link::before, .link::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  height: 1px;
  width: 100%;
}
.link::before { background: var(--hair); }
.link::after {
  background: var(--ag);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .55s var(--ease);
}
.link:hover::after, .link:focus-visible::after { transform: scaleX(1); }

.telno {
  font-family: var(--mono);
  font-size: .78rem;
  letter-spacing: .04em;
  color: var(--lume-2);
  font-variant-numeric: tabular-nums;
  transition: color .3s;
}
.telno:hover { color: var(--lume); }

/* --------------------------------------------------------------- media */

.shot { position: relative; }
.shot picture, .shot-i {
  display: block;
  overflow: hidden;
  background: var(--stone);
}
.shot img, .shot video {
  width: 100%;
  display: block;
  filter: saturate(.94) contrast(1.02);
  transform: scale(1.07);
  transition: transform 1.5s var(--ease), filter .7s ease;
}
.shot.in img, .shot.in video,
[data-rv].in .shot img, [data-rv].in .shot video { transform: scale(1); }
a.shot:hover img, .shot--hov:hover img { filter: saturate(1) contrast(1.04) brightness(1.06); }

.cap {
  display: block;
  margin-top: .85em;
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .06em;
  color: var(--lume-3);
  text-transform: uppercase;
}

.bleed {
  position: relative;
  overflow: hidden;
  background: var(--pitch);
}
.bleed video, .bleed img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Many stops, eased, plus grain. Three stops over a 900px height is what
   produced the visible steps in the earlier build. */
.bleed-scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg,
      rgba(8, 9, 11, .68) 0%, rgba(8, 9, 11, .52) 9%, rgba(8, 9, 11, .34) 19%,
      rgba(8, 9, 11, .20) 30%, rgba(8, 9, 11, .13) 42%, rgba(8, 9, 11, .16) 56%,
      rgba(8, 9, 11, .30) 70%, rgba(8, 9, 11, .52) 84%, rgba(8, 9, 11, .82) 100%);
}
.bleed-scrim::after,
.op-scrim::after,
.hero-veil::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: var(--grain);
  background-size: 140px 140px;
  opacity: .16;
  mix-blend-mode: overlay;
  pointer-events: none;
}

/* video controls: square, mono, no chrome */
.vplay, .vsound {
  position: absolute;
  z-index: 3;
  right: 16px;
  bottom: 16px;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  background: rgba(8, 9, 11, .58);
  box-shadow: inset 0 0 0 1px var(--hair);
  color: var(--lume);
  transition: background .3s, box-shadow .3s;
}
.vsound { right: 60px; }
.vplay:hover, .vsound:hover { background: rgba(8, 9, 11, .85); box-shadow: inset 0 0 0 1px var(--ag); }
.vplay[hidden] { display: none; }
.vplay svg, .vsound svg { width: 14px; height: 14px; }
.vsound .on { display: none; }
.vsound.is-on .on { display: block; }
.vsound.is-on .off { display: none; }

/* --------------------------------------------------------------- ledger */
/* The content-shaped alternative to cards: ruled rows, mono figures right. */

.ledger { border-top: 1px solid var(--hair); }
.led-r {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 1.4em;
  padding: clamp(15px, 1.9vh, 26px) 0;
  border-bottom: 1px solid var(--hair);
}
.led-n {
  font-family: var(--serif);
  font-size: clamp(1.06rem, 1.4vw, 1.34rem);
  color: var(--lume);
  line-height: 1.2;
}
.led-d {
  font-family: var(--sans);
  font-weight: 300;
  font-size: .92rem;
  color: var(--lume-3);
  line-height: 1.5;
  margin-top: .3em;
  max-width: 62ch;
}
.led-v {
  font-family: var(--mono);
  font-size: .74rem;
  letter-spacing: .05em;
  color: var(--ag);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* -------------------------------------------------------------- open light */

.olight {
  display: inline-flex;
  align-items: center;
  gap: .65em;
  font-family: var(--sans);
  font-weight: 400;
  font-size: .74rem;
  letter-spacing: .01em;
  text-transform: none;
  color: var(--lume-3);
}
.olight i {
  width: 5px;
  height: 5px;
  flex: none;
  border-radius: 50%;
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--lume-3);
}
.olight.is-open i { background: var(--ag); box-shadow: none; animation: rs-pulse 3.4s ease-in-out infinite; }
.olight.is-open { color: var(--lume); }
.olight.is-closed i { box-shadow: inset 0 0 0 1px rgba(243, 241, 236, .24); }
.olight--pending i { box-shadow: inset 0 0 0 1px var(--ag-dim); border-radius: 50%; }
@keyframes rs-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .42; } }

/* copy awaiting the client. A quiet mono italic note, never a chip or a pill. */
.pending-chip {
  font-family: var(--mono);
  font-style: italic;
  font-size: .7rem;
  letter-spacing: .04em;
  color: var(--lume-3);
}

/* ============================================================ site header */
/* Built against the references, not invented.
   designxhand: one ruled data row spanning the page, cells divided by vertical
   hairlines, each opened by a small ring, set in the TEXT face at 14px in
   sentence case. tecnoarreda: transparent over the opening, generous height, a
   wide thin two-line control at the far right. for-living / parallel universe:
   language as small caps, the active one lit and the rest dimmed.
   The header is the quietest thing on the screen. The drama is the page. */

.hd {
  position: fixed;
  inset: 0 0 auto;
  z-index: 90;
  height: var(--hd-h);
  background: transparent;
  transition: background .5s ease;
}
.hd.is-scrolled { background: var(--ink); }

.hd-row {
  height: 100%;
  max-width: none;
  margin-inline: auto;
  padding-inline: var(--gut);
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--hair-2);
}

.hd-cell {
  display: flex;
  align-items: center;
  gap: .85em;
  padding-inline: clamp(14px, 1.9vw, 34px);
  border-left: 1px solid var(--hair-2);
  font-family: var(--sans);
  font-weight: 300;
  font-size: .86rem;
  letter-spacing: .005em;
  line-height: 1;
  color: var(--lume-2);
  white-space: nowrap;
  min-width: 0;
  transition: color .35s ease;
}
.hd-cell:first-child { padding-left: 0; border-left: 0; }

/* the ring that opens a cell, jewellery scale */
.hd-o {
  width: 5px;
  height: 5px;
  flex: none;
  border: 1px solid var(--ag);
  border-radius: 50%;
  opacity: .85;
}

.hd-mark { gap: 12px; position: relative; z-index: 3; }
.hd-mark img { width: 20px; height: 24px; opacity: .92; transition: opacity .4s; }
.hd-mark:hover img { opacity: 1; }
.hd-word {
  font-family: var(--serif);
  font-size: 1.06rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--lume);
}

/* THE SLACK GOES BETWEEN THE TWO GROUPS, NEVER INSIDE A CELL.
   Letting the name cell take flex:1 made it 559px wide holding 200px of text,
   so its divider hung in the middle of an empty box and the bar read as a
   broken table. Every cell is now shrink-wrapped, the left group and the right
   group sit at the two ends, and the empty run between them carries no line.
   That is tecnoarreda's bar: a mark, one item, a long emptiness, the cluster. */
.hd-cell { flex: 0 0 auto; }
.hd-here, .hd-name { min-width: 0; }
.hd-name { max-width: 42ch; }
.hd-name span, .hd-here span { overflow: hidden; text-overflow: ellipsis; }

.hd-lang { gap: 1.05em; margin-left: auto; }
/* THE BURGER SITS ON THE GUTTER, AT EVERY WIDTH.
   <details> is the flex container for the summary, and Chromium keeps a marker
   box inside it even under list-style:none, so this cell's inherited flex gap
   (11.7px) was being reserved AFTER the summary: the mark started 72px from the
   left at 1440 while the rules stopped 84px from the right, and 20 against 32 on
   a phone. gap:0 is the fix, because the space was not free for
   justify-content or an auto margin to take. Fixed on mobile first and it had
   to be said again here: the rule belongs at the base, not in a breakpoint. */
.mfx.hd-cell {
  /* padding-inline:0 and the space taken as a MARGIN instead. With the cell's
     inherited 27px of left padding the glyph had 28px of void on one side of
     its box and 0 on the other: mirror-symmetric with the mark against the page
     edge, and visibly off-centre inside its own ruled cell, which is what reads
     as "pushed left". Zero padding makes the cell exactly the width of the
     rules, so the glyph is centred in it by construction AND its right edge
     still lands on the page gutter. The margin keeps the divider off the bars. */
  /* THE RULES SIT IN THE MIDDLE OF THEIR OWN CELL, and the cell runs to the
     page edge. Three attempts got this wrong in three different ways: flush to
     the page gutter (a 48px icon stranded 96px from the corner at 1920), then
     flush to the right of a padded cell (28px of void on one side, 0 on the
     other), then a tight cell pulled to the corner, which put the bars hard
     against the divider with all the space on their right. That is the state
     the client photographed.
     The cell now has EQUAL padding on both sides and its right edge is the
     viewport edge, so the space before the rules and the space after them are
     the same number by construction, at every width. */
  padding-inline: clamp(18px, 1.8vw, 30px);
  margin-left: clamp(6px, .8vw, 14px);
  margin-right: calc(var(--gut) * -1);
  gap: 0;
}
.hd-lang a {
  font-size: .78rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--lume-3);
  transition: color .3s;
}
.hd-lang a:hover { color: var(--lume-2); }
.hd-lang a.is-on { color: var(--lume); }

.hd-res { color: var(--lume); }
.hd-res:hover { color: #fff; }
.hd-res:hover .hd-o, .hd-mark:hover .hd-o { opacity: 1; }

/* the card, beside reservations, on a room's page only. It survives the 620px
   breakpoint that drops .hd-res: on a phone the first thing anyone wants from a
   restaurant is the menu, and the telephone is one tap away in the plate, in
   the INDEKS panel and in the footer. */
.hd-menu { color: var(--lume); }
.hd-menu:hover { color: #fff; }
.hd-menu:hover .hd-o { opacity: 1; }
.hd-menu[aria-current="page"] { color: var(--ag); }
.hd-menu[aria-current="page"] .hd-o { opacity: 1; }

/* --------------------------------------------------- the INDEKS manifest */

.mfx { position: relative; padding-right: 0; }
.mfx > summary {
  list-style: none;
  display: flex;
  align-items: center;
  height: 100%;
  color: var(--lume);
  cursor: pointer;
  position: relative;
  z-index: 3;
}
.mfx > summary::-webkit-details-marker { display: none; }
/* THE MARK. Two rules that converge and cross.
   Three things were fighting each other before: the bar's WIDTH animated while
   the rules turned, so they squashed mid-rotation; a leftover rule rotated and
   scaled the whole CONTAINER at the same time as its two children rotated
   inside it; and both used one transform, so travel and turn happened at once.
   Width is fixed now, the container never moves, and translate and rotate are
   separate properties so the motion is staged: opening travels then turns,
   closing turns then travels. */
.mfx > summary i {
  position: relative;
  display: block;
  width: clamp(38px, 3.4vw, 48px);
  height: 12px;
  opacity: .8;
  transition: opacity .4s ease;
}
.mfx > summary:hover i { opacity: 1; }

.mfx > summary i::before,
.mfx > summary i::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  margin-top: -0.5px;
  background: currentColor;
  transition: translate .34s var(--ease) .16s, rotate .34s var(--ease);
}
.mfx > summary i::before { translate: 0 -4.5px; rotate: 0deg; }
.mfx > summary i::after  { translate: 0 4.5px;  rotate: 0deg; }

.mfx[open] > summary i::before,
.mfx[open] > summary i::after {
  transition: translate .34s var(--ease), rotate .34s var(--ease) .16s;
}
.mfx[open] > summary i::before { translate: 0 0; rotate: 45deg; }
.mfx[open] > summary i::after  { translate: 0 0; rotate: -45deg; }

@media (prefers-reduced-motion: reduce) {
  .mfx > summary i::before, .mfx > summary i::after { transition: none; }
}


/* The panel paints INSIDE the header's stacking context, above the page and
   below the summary and the mark. z-index -1 would have put it behind the
   header's own scrolled background, which is where an earlier draft lost it. */
/* Chromium keeps the closed <details> slot in the layout tree, so the fixed
   panel's rows still measured 433px wide inside a 390px viewport and every page
   on the site reported horizontal overflow. Take it out of layout explicitly. */
.mfx:not([open]) .mfx-p { display: none; }
.mfx-p {
  position: fixed;
  inset: 0;
  z-index: 1;
  background: var(--ink);
  padding: calc(var(--hd-h) + clamp(24px, 5vh, 64px)) var(--gut) clamp(28px, 5vh, 60px);
  overflow-y: auto;
  display: grid;
  align-content: start;
  gap: clamp(26px, 4vh, 52px);
  animation: idx-in .45s var(--ease) both;
}
@keyframes idx-in { from { opacity: 0; } to { opacity: 1; } }

.mfx-grid {
  max-width: 1560px;
  width: 100%;
  margin-inline: auto;
  display: grid;
  grid-template-columns: minmax(200px, 27%) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 76px);
  align-items: start;
}
.mfx-pages { display: grid; gap: .32em; align-content: start; }
.mfx-pages a {
  font-family: var(--serif);
  font-size: clamp(1.5rem, 2.5vw, 2.3rem);
  line-height: 1.2;
  color: var(--lume-2);
  transition: color .3s;
  width: max-content;
  max-width: 100%;
}
.mfx-pages a:hover, .mfx-pages a:focus-visible { color: var(--lume); font-style: italic; }

.mfx-rooms { border-top: 1px solid var(--hair); }
.mfx-row {
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr) auto auto;
  align-items: baseline;
  gap: clamp(10px, 1.6vw, 26px);
  padding: clamp(9px, 1.2vh, 15px) 0;
  border-bottom: 1px solid var(--hair);
  transition: background .3s;
}
.mfx-row:hover { background: rgba(243, 241, 236, .028); }
.mfx-no {
  font-family: var(--mono);
  font-size: .68rem;
  color: var(--ag);
  font-variant-numeric: tabular-nums;
}
.mfx-nm {
  font-family: var(--serif);
  font-size: clamp(1.02rem, 1.5vw, 1.32rem);
  color: var(--lume);
  line-height: 1.2;
}
.mfx-row:hover .mfx-nm { font-style: italic; }
.mfx-ct {
  display: inline-flex;
  align-items: center;
  gap: .9em;
  font-family: var(--serif);
  font-size: .74rem;
  letter-spacing: .17em;
  text-transform: uppercase;
  color: var(--lume-3);
}
.mfx-ct .olight { display: none; }
.mfx-tel { font-family: var(--sans); font-weight: 300; font-size: .84rem; color: var(--lume-2); white-space: nowrap; }
.mfx-tel:hover { color: var(--lume); }

.mfx-foot {
  max-width: 1560px;
  width: 100%;
  margin-inline: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 14px clamp(20px, 3vw, 46px);
  align-items: baseline;
  border-top: 1px solid var(--hair);
  padding-top: clamp(16px, 2.4vh, 26px);
}
.mfx-foot em {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.06rem;
  color: var(--lume-2);
  flex: 1 1 260px;
}
.mfx-foot a {
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--lume-3);
}
.mfx-foot a.is-on, .mfx-foot a:hover { color: var(--lume); }

/* Two lines per address on a narrow panel: the name on the first, the city and
   the line on the second. Sharing one cell is what made them overlap. */
@media (max-width: 900px) {
  .mfx-grid { grid-template-columns: 1fr; }
  .mfx-row {
    grid-template-columns: 34px minmax(0, 1fr) auto;
    row-gap: 7px;
  }
  .mfx-no { grid-column: 1; grid-row: 1; }
  .mfx-nm { grid-column: 2 / -1; grid-row: 1; }
  .mfx-ct { grid-column: 2; grid-row: 2; }
  .mfx-tel { grid-column: 3; grid-row: 2; justify-self: end; }
}

/* ================================================================= footer */
/* Three tiers, not five: the statement, the directory, the base line.
   No marquee. */

.ft {
  position: relative;
  background: var(--ink);
  border-top: 1px solid var(--hair-2);
  padding-top: clamp(64px, 9vh, 120px);
}
.ft-in {
  max-width: 1560px;
  margin-inline: auto;
  padding-inline: var(--gut);
}

.ft-say {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(24px, 4vw, 64px);
  align-items: end;
  padding-bottom: clamp(46px, 7vh, 88px);
}
.ft-conceit {
  font-family: var(--serif);
  font-size: var(--t-h1);
  line-height: .98;
  letter-spacing: -.015em;
  color: var(--lume);
  max-width: 15ch;
}
.ft-tag {
  display: block;
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--lume-3);
  margin-bottom: 1.5em;
}
.ft-sub { margin-top: 1.5em; }
.ft-mark { position: relative; overflow: hidden; flex: none; }
.ft-mark img { width: clamp(54px, 7vw, 84px); height: auto; opacity: .62; }
/* the one silver shine, and the fifth job of the metal */
.ft-shine {
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 34%, rgba(169, 175, 178, .55) 50%, transparent 66%);
  transform: translateX(-115%);
}
.ft-mark.lit .ft-shine { animation: ft-shine 1.9s var(--ease) .25s both; }
@keyframes ft-shine { to { transform: translateX(115%); } }

.ft-h {
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--lume-3);
  font-weight: 400;
  margin: 0 0 2.4em;
}

.ft-dir { display: grid; gap: clamp(20px, 3vh, 34px); }
.fd-cc {
  display: block;
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ag);
  padding-bottom: .8em;
  border-bottom: 1px solid var(--hair);
}
.ft-dir > * + * { margin-top: clamp(18px, 3vh, 32px); }
.fd-row {
  display: grid;
  grid-template-columns: 34px minmax(0, 26ch) minmax(0, 1fr);
  align-items: baseline;
  gap: 0 clamp(14px, 2vw, 34px);
  padding: 12px 0;
  border-bottom: 1px solid var(--hair-2);
}
.fd-no { font-family: var(--mono); font-size: .66rem; color: var(--lume-3); }
.fd-name { font-family: var(--serif); font-size: 1.1rem; color: var(--lume); line-height: 1.2; }
.fd-row:hover .fd-name { font-style: italic; }
.fd-meta {
  display: flex;
  flex-wrap: wrap;
  gap: .3em clamp(12px, 2vw, 30px);
  font-family: var(--mono);
  font-size: .68rem;
  color: var(--lume-3);
}
.fd-meta a { color: var(--lume-2); }
.fd-meta a:hover { color: var(--lume); }
.fd-meta i { font-style: normal; color: var(--lume-3); }

.ft-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(138px, 1fr));
  gap: clamp(24px, 3vw, 52px);
  padding-block: clamp(44px, 6vh, 76px);
}
.ft-col { display: grid; align-content: start; gap: .55em; }
.ft-col b {
  font-family: var(--mono);
  font-weight: 400;
  font-size: .68rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ag);
  margin-bottom: .35em;
}
.ft-col a, .ft-col span {
  font-family: var(--sans);
  font-weight: 300;
  font-size: .9rem;
  color: var(--lume-3);
  transition: color .3s;
  width: max-content;
  max-width: 100%;
  /* max-width caps the box but a 31 character address has no break
     opportunity, so it overflowed the whole document at 390 */
  overflow-wrap: anywhere;
}
.ft-col a:hover, .ft-col a[aria-current] { color: var(--lume); }

.ft-base {
  display: flex;
  flex-wrap: wrap;
  gap: 12px clamp(18px, 3vw, 40px);
  align-items: center;
  border-top: 1px solid var(--hair-2);
  padding-block: 22px clamp(24px, 4vh, 40px);
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .06em;
  color: var(--lume-3);
}
.ft-top-link { margin-left: auto; display: inline-flex; align-items: center; gap: .6em; }
.ft-top-link svg { width: 9px; height: 11px; }
.ft-top-link:hover { color: var(--lume); }

@media (max-width: 900px) {
  .fd-row { grid-template-columns: 30px minmax(0, 1fr); }
  .fd-meta { grid-column: 2; margin-top: .42em; }
}
@media (max-width: 780px) {
  .ft-say { grid-template-columns: 1fr; align-items: start; }
  .ft-mark { order: -1; }
}
@media (max-width: 460px) {
  .ft-cols { grid-template-columns: 1fr; }
}

/* ================================================================= motion */
/* Five moves and nothing else. Everything finishes in one pass or runs on its
   own clock, so the page is composed at every scroll position. */

/* 1. Rise */
[data-rv] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .9s var(--ease), transform .9s var(--ease);
}
[data-rv].in { opacity: 1; transform: none; }

/* 2. Curtain: the mask is on the CHILD, never on the observed element.
   Either the <picture> pic() emits or an explicit .shot-i wrapper. */
.shot picture, .shot-i {
  clip-path: inset(0 0 100% 0);
  transition: clip-path 1.25s var(--ease);
}
[data-rv].in .shot picture, .shot.in picture, [data-rv].in .shot-i,
.shot.in .shot-i, .in > .shot-i { clip-path: inset(0 0 0 0); }

/* 3. Set line: a headline rises word by word out of its line box */
.hsplit .w {
  display: inline-block;
  transform: translateY(.92em);
  opacity: 0;
  transition: transform .95s var(--ease), opacity .7s ease;
  transition-delay: calc(var(--wi, 0) * 42ms);
}
.hsplit.in .w, h1.hsplit .w { transform: none; opacity: 1; }
h1.hsplit .w { transition-delay: calc(220ms + var(--wi, 0) * 42ms); }

/* the hero entrance, gated on html.rs-in so it cannot wait on window.load */
.rs-enter { opacity: 0; transform: translateY(20px); }
html.rs-in .rs-enter {
  opacity: 1;
  transform: none;
  transition: opacity 1.1s var(--ease), transform 1.1s var(--ease);
}
html.rs-in .rs-enter.d1 { transition-delay: .12s; }
html.rs-in .rs-enter.d2 { transition-delay: .26s; }
html.rs-in .rs-enter.d3 { transition-delay: .4s; }
html.rs-in .rs-enter.d4 { transition-delay: .54s; }

/* 4. Breath is per-page ambience, declared in the page stylesheet.
   5. Hover lives on the components above. */

/* the scroll cue: mono word plus a hairline with a mark travelling it */
.descend {
  display: inline-flex;
  align-items: center;
  gap: 1em;
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--lume-3);
}
.descend::before {
  content: '';
  width: 54px;
  height: 1px;
  background: var(--hair);
  position: relative;
  overflow: hidden;
  flex: none;
  background-image: linear-gradient(90deg, var(--ag), var(--ag));
  background-size: 18px 1px;
  background-repeat: no-repeat;
  animation: rs-travel 3.4s cubic-bezier(.6, 0, .4, 1) infinite;
}
@keyframes rs-travel {
  0%   { background-position: -18px 0; }
  70%, 100% { background-position: 54px 0; }
}

/* Ken Burns for media beds: autonomous, 26s, never scroll-linked */
.kb { animation: rs-kb 26s ease-in-out infinite alternate; transform-origin: 50% 55%; }
@keyframes rs-kb { from { transform: scale(1.03); } to { transform: scale(1.11); } }

[id] { scroll-margin-top: calc(var(--hd-h) + 18px); }

/* ------------------------------------------------------- reduced motion */
/* Not disabled: FINISHED. Every move lands on its end state. */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  html::before { animation: none; opacity: .86; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  [data-rv], .rs-enter { opacity: 1 !important; transform: none !important; }
  .shot picture, .shot-i { clip-path: none !important; }
  .shot img, .shot video { transform: none !important; }
  .hsplit .w { transform: none !important; opacity: 1 !important; }
  .kb { animation: none !important; transform: none !important; }
  .olight.is-open i { animation: none !important; }
  .ft-shine { display: none; }
}

/* ------------------------------------------------------------ small screens */

@media (max-width: 1024px) {
  :root { --hd-h: 66px; }
  .hd-name { display: none; }
  .hd-cell { padding-inline: clamp(14px, 2.2vw, 28px); }
  /* air is a desktop luxury: at 390 the same value reads as a dead screen */
  .sec--air { --pad: clamp(86px, 11vh, 130px); }
  .sec { --pad: clamp(72px, 9vh, 112px); }
}
/* ---------------------------------------------------------------- the phone
   Everything above is sized for a 1440 canvas. At 390 the same letterspacing
   turns a two word label into two lines, and the same header type fills the
   whole bar. This block is the mobile design, not a set of patches. */

@media (max-width: 700px) {
  /* the label register tightens: .19em is a printed caption, not a phone one */
  .mono, .chap-w, .plate-k, .fd-cc, .ft-h, .ft-tag, .cap, .mfx-ct, .ft-col b,
  .hero-intro, .hero-kick, .hero-cap, .hero-note, .res-g dt, .res-g b, .res-g .res-l {
    letter-spacing: .11em !important;
    font-size: .7rem !important;
  }
  .plate-name { letter-spacing: .12em; font-size: .78rem; }
  .chap-no, .plate-no { font-size: .84rem; }
  .lede { font-size: clamp(1.04rem, .96rem + .6vw, 1.2rem); }
  .prose { font-size: 1.02rem; line-height: 1.62; }
  .act { padding: .95em 1.35em; font-size: .86rem; }
  h3 { font-size: clamp(1.2rem, 5.2vw, 1.5rem); }
}

@media (max-width: 760px) {
  .hd-here { display: none; }
  .hd-cell { padding-inline: clamp(12px, 3vw, 20px); }
}

@media (max-width: 620px) {
  :root { --hd-h: 58px; --gut: 20px; }
  /* THE BURGER SITS ON THE GUTTER, like the mark on the other side.
     The cell is 57px wide but its rules are only 32px, and with the default
     flex-start the glyph ended 12px short of the cell's own edge, which is
     another 20px of gutter further in: the mark started 20px from the left
     while the burger stopped 32px from the right, and the header read as
     visibly lopsided on every phone. */
  /* the gap:0 that squares the burger with the gutter now lives on the base
     rule, so it applies at every width */
  .mfx > summary { margin-left: auto; }
  .hd-word { font-size: .82rem; letter-spacing: .13em; }
  .hd-mark { gap: 9px; }
  .hd-mark img { width: 17px; height: 20px; }
  .hd-res { display: none; }
  .hd-lang { gap: .8em; border-left: 0; }
  /* the three language links were 12px tall, which is a third of the smallest
     tap target anyone recommends. The text does not change size: the padding
     gives each one a finger sized box inside the bar. */
  .hd-lang a { font-size: .74rem; padding-block: .95em; }
  .mfx > summary i { width: 32px; height: 11px; }
  .mfx-pages a { font-size: 1.5rem; }
  .descend::before, .op-down i { display: none !important; }
  .mfx-p { padding-top: calc(var(--hd-h) + 26px); }
  .mfx-row { grid-template-columns: 28px minmax(0, 1fr) auto; gap: 7px 10px; padding: 13px 0; }
  .mfx-nm { font-size: 1.12rem; }
  .mfx-foot em { font-size: .96rem; }
  .skip { font-size: .68rem; }
}

@media (max-width: 430px) {
  :root { --hd-h: 56px; }
  .hd-word { font-size: .76rem; letter-spacing: .1em; }
  .hd-mark img { width: 15px; height: 18px; }
  .mfx-pages a { font-size: 1.32rem; }
}

/* ============================================================== THE THREAD
   One silver hairline weaving the whole document, drawn as you descend.
   It sits behind every section (sections that paint a ground are opaque, so
   the thread reads through the transparent ones and through the voids, which
   is where it belongs). Its length at any scroll position is definite: there
   is no state in which it is half built. */

/* The layering, which is the whole trick: the thread sits ABOVE every section
   ground, so it is never swallowed by a banded section, and BELOW the elements
   that matter, so it passes behind photographs, video beds and controls. Where
   it crosses reading copy it is not moved out of the way, it is dimmed, which
   is what the gradient in site.js does band by band.

   Sections therefore must NOT be positioned: giving them a z-index is what put
   the line underneath them and made it disappear for most of the page. */
.thread {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1;
  pointer-events: none;
  /* belt and braces against the empty scroll at the foot of the page: even if
     the SVG is ever sized a little long, it cannot push the document open.
     site.js measures the footer's bottom rather than scrollHeight so that this
     should never be load bearing. */
  height: 0;
  overflow: visible;
}
.thread svg { display: block; width: 100%; }
/* No thread on phones, in CSS as well as in site.js: the document-height
   masked SVG is what dropped mobile scrolling to a slideshow, and this rule
   holds even in the window between first paint and the script's decision. */
@media (max-width: 919px) { .thread { display: none; } }
body { position: relative; }
main > section:not([class*="gnd-"]) { background: transparent; }

/* THE THREAD MUST NOT BE BURIED, AND THIS IS WHY IT KEEPS HAPPENING.
   The rule above says sections must not be positioned. Page stylesheets keep
   writing `.sec { position: relative; z-index: 1 }` anyway, because a section
   usually does need position:relative for its own absolutely positioned parts,
   and the z-index comes along out of habit. The moment it does, that section
   and its opaque ground paint OVER the thread, which sits at z-index 1 earlier
   in the document. The line then survives exactly as far as the first section
   with a transparent background and vanishes for the rest of the page. Reported
   on the flagship on 2026-08-01; every location stylesheet had the same line.

   position stays, because pages genuinely need it. Only the stacking level is
   taken back, which is what this file always assumed. `!important` because
   per-page stylesheets load after this one and would otherwise win.

   The opening keeps its own layer on purpose: the thread is meant to pass
   BEHIND the hero photograph, not across it. */
main > section, main > div { z-index: auto !important; }
main > .hero, main > .opening { z-index: 1 !important; }

/* in front of the thread: anything with a physical presence */
/* .mfx-p is NOT in this list. It is the fixed INDEKS overlay, and because this
   block sits later in the file than the header rules, naming it here quietly
   overrode position:fixed with position:relative and the panel opened laid out
   inside the header row: top -315, left 1060, 1378 wide. That is the "broken
   hamburger". Nothing that is position:fixed belongs in this list. */
main figure, main picture, .shot, .frw, .fr, .bleed, .strip, .strip-c,
.mf-stage, .brd-ph, .hero-ph, .hero-bg, .hero-veil, .op-bed, .op-scrim,
main video, .act, .ft-mark, .plate {
  position: relative;
  z-index: 2;
}
.hd, .skip { z-index: 90; }

/* ------------------------------------------------- scroll-borne composition
   Five moves was too few: the client read the result as static. These are
   scroll-BORNE rather than scroll-scrubbed. Each is a finite offset applied to
   an element that is fully drawn at every position, so stopping anywhere still
   catches a composed frame. */

/* a photograph drifts slower than the page it sits on */
[data-drift] { will-change: transform; }

/* the figure inside a frame breathes a little as it crosses */
.shot picture, .fr picture { transform: translateZ(0); }

/* THE CURTAIN, applied by site.js to every in-flow photograph without a
   mechanic of its own. The clip is on the CHILD picture, never on the observed
   figure: a zero-area observed element can never intersect and can therefore
   never open. See the note on .shot picture above, same rule, same reason. */
.rs-cur picture {
  display: block;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 1.15s var(--ease);
}
.rs-cur.in picture { clip-path: inset(0 0 0 0); }
/* the frame settles out of a slight push, so the photograph arrives rather
   than appears. Small enough that any single frame reads as a still. */
.rs-cur img { transform: scale(1.05); transition: transform 1.8s var(--ease); }
.rs-cur.in img { transform: none; }

/* a caption lands after the frame it belongs to, not with it */
[data-rv] .cap, [data-rv] figcaption, [data-rv] .pcap, [data-rv] .fcap {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .6s var(--ease) .38s, transform .6s var(--ease) .38s;
}
[data-rv].in .cap, [data-rv].in figcaption,
[data-rv].in .pcap, [data-rv].in .fcap { opacity: 1; transform: none; }

/* RULED LISTS arrive row by row. --li is the row index, set by site.js. */
.rs-stg > * {
  opacity: 0;
  transform: translateY(9px);
  transition:
    opacity .62s var(--ease) calc(var(--li, 0) * 52ms),
    transform .62s var(--ease) calc(var(--li, 0) * 52ms);
}
.rs-stg.in > * { opacity: 1; transform: none; }

/* the fixed bar assembles once, on the first paint, cell by cell */
.hd-row > * {
  opacity: 0;
  transform: translateY(-7px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
html.rs-in .hd-row > * { opacity: 1; transform: none; }
.hd-row > *:nth-child(1) { transition-delay: .04s; }
.hd-row > *:nth-child(2) { transition-delay: .11s; }
.hd-row > *:nth-child(3) { transition-delay: .18s; }
.hd-row > *:nth-child(4) { transition-delay: .25s; }
.hd-row > *:nth-child(5) { transition-delay: .32s; }
.hd-row > *:nth-child(6) { transition-delay: .39s; }
.hd-row > *:nth-child(7) { transition-delay: .46s; }

/* a headline's rule draws itself in one pass as the chapter arrives */
.chap-m { position: relative; }
.chap-m::after {
  content: '';
  position: absolute;
  right: -1px;
  top: 0;
  width: 1px;
  height: 100%;
  background: var(--ag-dim);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 1.1s var(--ease);
}
.chap.in .chap-m::after, [data-rv].in .chap-m::after { transform: scaleY(1); }

/* ----------------------------------------------------- the WhatsApp dock
   One floating control, bottom right, carrying the number of the room being
   read (lib/dock.js resolves it). Square corners like everything else on this
   site: the pill is the one shape V6 does not own. z-index sits under the
   header and the INDEKS panel so it can never cover navigation, and it clears
   itself out of the way when the panel opens or the footer arrives. */

/* ONE ruled block, not two buttons: the header of this site is a row of cells
   divided by vertical hairlines, and this is that row at 92 by 46. Dark glass
   over the page, one hairline down the middle, a silver glyph in each half. No
   fill, no label, no colour, because the page behind it is the thing that is
   meant to be loud. */
.rs-dock {
  position: fixed;
  right: var(--corner);
  bottom: var(--corner);
  z-index: 70;
  display: flex;
  align-items: stretch;
  background: rgba(8, 9, 11, .66);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  box-shadow: inset 0 0 0 1px var(--hair), 0 18px 40px -18px rgba(0, 0, 0, .95);
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity .5s var(--ease), transform .5s var(--ease), box-shadow .4s;
}
.rs-dock.is-on { opacity: 1; transform: none; pointer-events: auto; }
/* the only thing it ever hides from is the full screen INDEKS overlay */
html.rs-lock .rs-dock {
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
}
/* BOTH CELLS ARE THE SAME SQUARE. Neither action outranks the other and a
   reservation button wider than the WhatsApp one made the pair look accidental.
   Fixed width and height, not padding: a label can grow, a square cannot. */
.rs-c {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 46px;
  width: 46px;
  height: 46px;
  color: var(--lume-2);
  transition: color .3s var(--ease), background .3s var(--ease);
}
.rs-c + .rs-c { border-left: 1px solid var(--hair); }
.rs-c svg { width: 19px; height: 19px; display: block; }
/* the WhatsApp mark is a fill, the handset is a stroke: both resolve to the
   same silver, so the pair reads as one set rather than two logos */
.rs-wa svg { fill: currentColor; }
@media (hover: hover) {
  .rs-c:hover { color: var(--lume); background: rgba(243, 241, 236, .06); }
  .rs-dock:hover {
    box-shadow: inset 0 0 0 1px var(--ag-dim), 0 18px 40px -18px rgba(0, 0, 0, .95);
  }
}
@media (max-width: 560px) {
  .rs-c { flex-basis: 44px; width: 44px; height: 44px; }
  .rs-c svg { width: 18px; height: 18px; }
}

@media (prefers-reduced-motion: reduce) {
  .thread { display: none; }
  [data-drift] { transform: none !important; }
  .chap-m::after { transform: scaleY(1) !important; }
  /* the dock still appears and disappears, it just does not travel */
  .rs-dock { transform: none !important; }
  /* every one of the 2026-08-01 moves lands on its FINISHED state, never on a
     disabled one: a curtain that is half shut is a broken page, not a calm one */
  .rs-cur picture { clip-path: none !important; transition: none !important; }
  .rs-cur img { transform: none !important; }
  .rs-stg > *, .hd-row > *,
  [data-rv] .cap, [data-rv] figcaption, [data-rv] .pcap, [data-rv] .fcap {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* the studio credit in the footer base line is a link home */
.ft-by { border-bottom: 1px solid var(--hair); transition: border-color .3s var(--ease), color .3s; }
.ft-by:hover { color: var(--lume); border-bottom-color: var(--ag); }

/* ------------------------------------------------- the header on a narrow phone
   A room's page carries four cells: the mark, three languages, the card and the
   burger. At 360 that measured 356px of content against 345px available, so the
   row overflowed and the burger's gutter collapsed from 20px to 4px while the
   mark kept its full 20. The wordmark is what gives: the logo beside it is
   already the link home, and it is the one cell whose meaning survives being
   dropped. Everything else in that row is a destination. */
@media (max-width: 420px) {
  .hd-word { display: none; }
  .hd-mark { gap: 0; }
}

/* ============================================== THE INDEKS PANEL WRAPS ITS TEXT
   `.hd-cell` sets white-space:nowrap, and <details class="mfx hd-cell"> is an
   ANCESTOR of the overlay, so every line in the panel inherited it. position:
   fixed takes an element out of layout; it does not take it out of the cascade.

   The result on a phone: the panel's grid measured 1177px inside a 360px
   viewport, so the site's only mobile navigation scrolled sideways and each
   room's reservations number sat off screen to the right, past an edge with
   nothing to suggest there was anything beyond it. The two column rule at
   max-width:900px below was working perfectly and could not help, because a
   minmax(0,1fr) column cannot shrink around text that refuses to wrap.

   Set at .mfx-p rather than on the row classes so that anything added to the
   panel later inherits the correct value instead of the header's. */
.mfx-p { white-space: normal; }
/* the one line in there that genuinely must not break */
.mfx-p .mfx-tel { white-space: nowrap; }

/* THE PANEL SCROLLS UNDER ITS OWN CLOSE BUTTON.
   .mfx-p is a fixed sheet with its own overflow-y, and the header sits above it
   at z-index 90 with no ground of its own, so the first rooms passed straight
   through the mark and the X on the way up. A scrim the height of the bar, on
   the panel's own layer, under the header and over the list. */
.mfx[open]::before {
  content: '';
  position: fixed;
  inset: 0 0 auto 0;
  height: var(--hd-h);
  background: var(--ink);
  z-index: 2;
  pointer-events: none;
}

/* =================================================== the cookie notice
   Ships hidden; /assets/consent.js is the only thing that reveals it. It is a
   sheet on the ink, ruled like everything else on this site, with no radius and
   no shadow: the same furniture as the INDEKS panel, one tier smaller.

   It sits ABOVE the WhatsApp dock (z-index 70) and BELOW the header (90),
   because it must not cover the language switcher a Russian visitor needs in
   order to read it. */
.ck {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 80;
  /* ONE VALUE FOR THE SIDE AND FOR THE BOTTOM, and it is the page gutter.
     These were two different clamps, which put the card 96px from the right
     edge and 26px from the bottom at 1920: the corner read as a mistake because
     it was one. Using --gut for both makes the two gaps equal by construction
     at every width, and it lands the card's right edge exactly on the site's
     content column, so the notice lines up with the page instead of floating
     near it. Never reintroduce a second spacing value here. */
  /* ONE VALUE FOR THE SIDE AND FOR THE BOTTOM, and it is the corner inset the
     WhatsApp dock already uses, because the notice and the dock occupy the same
     corner and one replaces the other. It was two different clamps once (96px
     from the right, 26px from the bottom at 1920) and then the full page gutter,
     which was equal but far too much air at a wide viewport. Never reintroduce
     a second spacing value here. */
  padding: 0 var(--corner) var(--corner);
  pointer-events: none;
}
.ck[hidden] { display: none; }
.ck-card {
  pointer-events: auto;
  max-width: 720px;
  margin-left: auto;
  background: rgba(8, 9, 11, .93);
  backdrop-filter: blur(16px) saturate(1.15);
  -webkit-backdrop-filter: blur(16px) saturate(1.15);
  box-shadow: inset 0 0 0 1px var(--hair), 0 26px 60px -26px rgba(0, 0, 0, .96);
  padding: clamp(18px, 2.4vw, 26px) clamp(18px, 2.4vw, 28px);
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .5s var(--ease), transform .5s var(--ease);
}
.ck.is-on .ck-card { opacity: 1; transform: none; }

/* the notice's own title. Serif, because every other heading on this site is,
   and because an unstyled first line reads as the first sentence of the body
   rather than as the name of the thing you are being asked about. */
.ck-h {
  font-family: var(--serif);
  font-size: clamp(1.12rem, 1.5vw, 1.34rem);
  line-height: 1.2;
  color: var(--lume);
  margin-bottom: .55em;
}

/* the link to the policy. It is the only route to the cookie table, the legal
   basis and the rights section, so it is underlined and it is not a whisper. */
.ck-more { margin-top: .7em; }
.ck-more a {
  font-family: var(--sans);
  font-weight: 400;
  font-size: .84rem;
  color: var(--lume);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .32em;
  text-decoration-color: var(--ag-dim);
  transition: text-decoration-color .3s;
}
.ck-more a:hover { text-decoration-color: var(--ag); }

.ck-text {
  font-family: var(--sans);
  font-weight: 300;
  font-size: .92rem;
  line-height: 1.55;
  color: var(--lume-2);
  max-width: 58ch;
}

.ck-act {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px clamp(12px, 1.4vw, 18px);
  margin-top: clamp(14px, 1.8vw, 20px);
}
/* Accept and Reject are typographically identical. See lib/consent.js. */
.ck-b {
  flex: 0 0 auto;
  min-width: 8.5em;
  padding: .92em 1.5em;
  background: none;
  color: var(--lume);
  font-family: var(--sans);
  font-weight: 400;
  font-size: .86rem;
  letter-spacing: .01em;
  line-height: 1;
  text-align: center;
  box-shadow: inset 0 0 0 1px var(--hair);
  cursor: pointer;
  transition: box-shadow .35s var(--ease), color .35s, background .35s;
}
.ck-b:hover { box-shadow: inset 0 0 0 1px var(--ag); background: rgba(243, 241, 236, .04); }
.ck-lk {
  background: none;
  border: 0;
  padding: .5em 0;
  font-family: var(--sans);
  font-weight: 300;
  font-size: .82rem;
  color: var(--lume-3);
  cursor: pointer;
  /* UNDERLINED, NOT BORDER-BOTTOMED. On a phone this button takes a row of its
     own (flex-basis:100%), and a border-bottom draws across the full width of
     the box, which read as a divider ruled across the card rather than as an
     underline under a word. A text-decoration underlines the text and nothing
     else, at any box width, so the two layouts agree. */
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .4em;
  text-decoration-color: var(--hair);
  transition: color .3s, text-decoration-color .3s;
}
.ck-lk:hover { color: var(--lume); text-decoration-color: var(--ag); }

.ck-p {
  margin-top: clamp(16px, 2vw, 22px);
  border-top: 1px solid var(--hair);
  padding-top: clamp(14px, 1.8vw, 20px);
  display: grid;
  gap: clamp(14px, 1.8vw, 18px);
}
.ck-p[hidden] { display: none; }

.ck-opt { display: grid; grid-template-columns: 40px minmax(0, 1fr); gap: 14px; align-items: start; }
.ck-opt-t {
  font-family: var(--sans);
  font-weight: 400;
  font-size: .84rem;
  color: var(--lume);
  line-height: 1.3;
}
.ck-opt-d {
  font-family: var(--sans);
  font-weight: 300;
  font-size: .8rem;
  line-height: 1.5;
  color: var(--lume-3);
  margin-top: .3em;
}

/* A square switch, because this site has no border-radius in it anywhere.
   The knob is a square that travels, and the state is carried by aria-checked
   rather than a class, so the switch and the screen reader can never disagree. */
.ck-sw {
  position: relative;
  width: 38px;
  height: 20px;
  flex: none;
  margin-top: .1em;
  padding: 0;
  border: 0;
  background: rgba(243, 241, 236, .09);
  box-shadow: inset 0 0 0 1px var(--hair);
  cursor: pointer;
  transition: background .3s var(--ease), box-shadow .3s;
}
.ck-sw::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 14px;
  height: 14px;
  background: var(--lume-3);
  transition: transform .3s var(--ease), background .3s var(--ease);
}
.ck-sw[aria-checked="true"] { background: rgba(169, 175, 178, .22); box-shadow: inset 0 0 0 1px var(--ag-dim); }
.ck-sw[aria-checked="true"]::after { transform: translateX(18px); background: var(--ag); }
.ck-sw[aria-disabled="true"] { cursor: default; opacity: .62; }

.ck-b:focus-visible, .ck-lk:focus-visible, .ck-sw:focus-visible {
  outline: 1px solid var(--ag);
  outline-offset: 3px;
}

/* the notice owns the bottom right corner while it is up, so the dock steps
   aside rather than sitting on top of the Accept button */
.ck.is-on ~ .rs-dock, .ck.is-on + .rs-dock { opacity: 0; pointer-events: none; }

@media (max-width: 620px) {
  /* no padding-inline override here: --gut is already 20px at this size, and a
     third spacing value is what broke the corner in the first place */
  .ck-card { margin-left: 0; padding: 18px 16px; }
  .ck-text { font-size: .88rem; }
  /* the two answers share the row and are exactly half of it each */
  .ck-b { flex: 1 1 0; min-width: 0; padding: .95em .6em; }
  .ck-lk { flex: 1 0 100%; text-align: left; }
  .ck-opt { grid-template-columns: 38px minmax(0, 1fr); gap: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  .ck-card { transition: none; }
  .ck-sw, .ck-sw::after { transition: none; }
}

/* the way back into the cookie notice, in the footer base line */
.ft-ck {
  background: none;
  border: 0;
  padding: 0;
  font-family: var(--sans);
  font-weight: 300;
  font-size: inherit;
  color: var(--lume-3);
  cursor: pointer;
  border-bottom: 1px solid var(--hair);
  transition: color .3s var(--ease), border-color .3s var(--ease);
}
.ft-ck:hover { color: var(--lume); border-bottom-color: var(--ag); }
