/* Founders Coffee — site styles.
   Layout and colour live in inline style attributes on the elements themselves
   (that is how the design was authored, it reads well in context, and it gzips
   to almost nothing). This file carries only what an inline style cannot do:
   pseudo-states, keyframes, media queries and focus rings. */

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:#1c1a16}
img{display:block;max-width:100%}

/* While a photograph is still arriving, its box paints the alt text. On a 3G
   connection the hero cannot decode before first paint — that is network
   physics, not a defect — so without this the first thing a visitor sees is the
   words "Founders around the Founders Coffee table" where the picture should be,
   and the archive reads as a wall of dates.

   An ink ground with transparent text makes the degraded state a quiet block
   that matches the design instead of stray words. The alt text is untouched in
   the accessibility tree, so screen readers still announce it; only the visual
   fallback changes. Once the bitmap decodes it covers both.

   Applies to every image, not just lazy ones: the hero is eager and is exactly
   the one that must never flash. */
img{background-color:#262219;color:transparent}
a{color:#1c1a16;text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:3px}
::selection{background:#f2d64d;color:#1c1a16}
input,textarea,button{font-family:inherit}
input::placeholder,textarea::placeholder{color:#6b6b6b;opacity:1}
[data-on-ink]::placeholder{color:#8f8b80;opacity:1}

/* Visible focus for keyboard users on every interactive element. */
input:focus-visible,textarea:focus-visible,button:focus-visible,
summary:focus-visible,a:focus-visible,[tabindex]:focus-visible{
  outline:3px solid #a83c1c;outline-offset:2px}

details>summary{list-style:none;cursor:pointer}
details>summary::-webkit-details-marker{display:none}

/* ---------------------------------------------------------------- motion */
@keyframes fcRise{from{opacity:0;transform:translateY(26px)}to{opacity:1;transform:translateY(0)}}
@keyframes fcPartners{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@keyframes fcBlink{0%,45%{opacity:1}50%,95%{opacity:.15}100%{opacity:1}}
@keyframes fcSteam{0%{opacity:.3;transform:translateY(2.5px) scaleY(.82)}
  50%{opacity:1;transform:translateY(-2px) scaleY(1.06)}
  100%{opacity:.3;transform:translateY(2.5px) scaleY(.82)}}

.fcLogo path{transform-box:fill-box;transform-origin:center}
.fcLogo path:nth-of-type(1){animation:fcSteam 2.6s ease-in-out infinite}
.fcLogo path:nth-of-type(2){animation:fcSteam 2.6s ease-in-out infinite .45s}
.fcLogo path:nth-of-type(3){animation:fcSteam 2.6s ease-in-out infinite .9s}

/* Reduced motion: stop the decorative loops and the long entrance reveals, but
   keep short state-change transitions — killing those outright removes the
   feedback that tells someone their click registered. */
@media (prefers-reduced-motion:reduce){
  .fcLogo path,[data-reveal],[data-parallax],.fcPartnerTrack{
    animation:none!important;transform:none!important;opacity:1!important;clip-path:none!important}
  [data-rv=step]::after{display:none!important}
  .fc-pip,.fc-pips{animation:none!important}
  *{transition-duration:.01ms!important;scroll-behavior:auto!important}
  a,button,summary,input,textarea,[data-fc]{transition-duration:.15s!important}
}

/* --------------------------------------------------------------- controls */
.fcx{scrollbar-width:thin}
.fcx::-webkit-scrollbar{height:3px}
.fcx::-webkit-scrollbar-track{background:rgba(16,16,16,.1)}
.fcx::-webkit-scrollbar-thumb{background:#1c1a16}

.fc-hover-color{transition:filter .4s ease}
.fc-hover-color:hover{filter:none!important}

/* Hover states the original template carried as inline hover attributes. */
.fc-link-ink:hover{color:#1c1a16}
.fc-btn-ink:hover{background:#1c1a16}
.fc-btn-underline:hover{text-decoration:underline}
.fc-btn-rust:hover{background:rgba(168,60,28,.09)}
.fcPartnerTrack:hover{animation-play-state:paused}

/* ------------------------------------------------------------------- FAQ */
.fcFaqBody{display:grid!important;grid-template-rows:0fr;
  transition:grid-template-rows .4s cubic-bezier(.16,1,.3,1)}
.fcFaqBody>.fcFaqBodyInner{overflow:hidden;min-height:0}
details[open]>.fcFaqBody{grid-template-rows:1fr}
.fcFaqIcon{display:inline-block;transition:transform .3s cubic-bezier(.16,1,.3,1)}
details[open] .fcFaqIcon{transform:rotate(45deg)}

/* ------------------------------------------------------- reveal on scroll
   Content is visible by default. Hiding is opt-in, switched on by JS only once
   it has confirmed it can actually measure the viewport — so if the observer
   never fires, or an extension interferes, the page shows its content instead
   of forty-seven invisible elements holding their full height. Shipped the
   other way round on 23 Aug 2026 and blanked most of the page. */
html.reveal-on [data-reveal]{opacity:0;transform:translateY(16px);
  transition:opacity var(--fc-enter) var(--fc-ease-out),transform var(--fc-enter) var(--fc-ease-out),
             clip-path var(--fc-enter) var(--fc-ease-out)}
/* The stagger lives on the ARRIVED state, because a transition takes its delay from the style it is
   moving TO. site.js sets --rv-i per sibling and marks .rv-done once the entrance has played, which
   drops the delay again so a later hover responds at once instead of waiting its turn. */
html.reveal-on [data-reveal].is-in{opacity:1;transform:none;transition-delay:calc(var(--rv-i,0) * var(--fc-stagger))}
html.reveal-on [data-reveal].rv-done{transition-delay:0s}

/* Anything JS drives is hidden only once JS confirms it is running, so the
   no-JS experience still shows real content instead of empty boxes. */
.js [data-js-hidden]{display:none}

/* ------------------------------------------------------------ sticky nav */
/* Shrinks once the page has scrolled past the hero's first 40px. Height is the
   honest property to animate here: the bar genuinely occupies less space, and
   the content below must move up with it. It is one element, once per scroll
   direction change — not a list, and not per-frame. */
.fc-nav{height:66px;transition:height .3s cubic-bezier(.16,1,.3,1)}
.fc-nav.is-shrunk{height:52px}
.fc-nav .fcLogo{width:30px;height:30px;transition:width .3s cubic-bezier(.16,1,.3,1),height .3s cubic-bezier(.16,1,.3,1)}
.fc-nav.is-shrunk .fcLogo{width:24px;height:24px}
@media (prefers-reduced-motion:reduce){
  .fc-nav,.fc-nav .fcLogo{transition:none}
}

/* ------------------------------------------------------------ press state
   Every pressable thing shrinks a little while it is held. Nothing here is
   decoration: without it a tap on a phone produces no acknowledgement at all
   between the finger going down and the network coming back, and the honest
   reading of that silence is "it didn't register", so people tap again.

   160ms and 0.97 are deliberately small. The effect should be felt rather than
   seen. transform only, so it stays on the compositor and cannot cost a frame.

   Kept out of the reduced-motion block on purpose: this is feedback, not
   movement, and someone who has asked for less motion still needs to know the
   button heard them. The existing rule already shortens it to 150ms. */
button,summary,[role="button"],a.fc-btn-ink,a.fc-btn-rust,a.fc-btn-underline,
a.fc-share-tg,a.fc-share-wa{
  transition:transform 160ms cubic-bezier(.16,1,.3,1)}
button:active,summary:active,[role="button"]:active,
a.fc-btn-ink:active,a.fc-btn-rust:active,a.fc-btn-underline:active,
a.fc-share-tg:active,a.fc-share-wa:active{
  transform:scale(.97)}

/* The archive tiles are already small; scaling them the full amount reads as a
   glitch rather than a press. */
.fcx button:active{transform:scale(.985)}

/* --------------------------------------------------- the header, on a phone
   Measured 26 Aug 2026 at 320px: the nav is flex, the brand is `flex:0 0 auto`
   and eats 224px of a 288px usable line, so the right-hand group was pushed
   clean off the viewport. The section links, the language chips AND "Take a
   chair" - the only conversion on the page - were all unreachable on a phone,
   with no hamburger and nothing to fall back on. The document did not scroll
   horizontally, which is why every overflow check passed: the header simply
   ended past the edge, silently.

   This is a composition, not a squeeze. The four section links are in-page
   anchors (#format, #gallery, #talk, #faq) on a single-scroll page, so on a
   phone they are the thing that can go: everything they point at is reached by
   scrolling, and the footer carries them too. What must survive is the brand,
   the language switch, and the CTA. */
@media (max-width: 760px){
  /* !important is load-bearing here, not laziness. This page is design-captured
     markup: every element carries its own `style` attribute, and an inline
     declaration beats any stylesheet rule that is not marked. Without it this
     rule silently lost - the container stayed `display:flex` and merely
     collapsed to 0px, which looks identical in a screenshot but leaves four
     links in the tab order pointing at things nobody can see. Anything this
     stylesheet overrides on this page needs the same treatment. */
  header nav > div:nth-of-type(1){display:none !important}

  /* With the links gone the right-hand group is the only flexible thing left,
     so let it shrink rather than run past the edge, and close the gap it no
     longer needs. Measured before this: the CTA ended at 322px in a 320 viewport. */
  header nav{gap:10px !important}
  header nav > div:nth-of-type(2){flex:0 1 auto !important;min-width:0}
}

/* The wordmark has to go well before 380px, which is where this was first set and
   it was wrong. Measure it rather than guess: brand 224 + gap 10 + language chips
   90 + gap 10 + CTA 145 = 479, plus 32 of padding = 511. So anywhere under ~520px
   the wordmark cannot coexist with the CTA, and the CTA is the one that matters.
   At 380 it looked fixed only because the 320 case had been checked and the
   awkward middle had not: at 390 the button still ran to 498px in a 390 viewport.
   The mug carries the brand alone - it is the same mark as the favicon. */
@media (max-width: 520px){
  header nav > a[href="#top"] > span{
    position:absolute;width:1px;height:1px;overflow:hidden;
    clip-path:inset(50%);white-space:nowrap}
}

/* THE SAME TRADE, ONE BAND HIGHER - and here it is not cosmetic, it is a nav item nobody
   can reach. Measured 12 Sep 2026 in the browser, both languages, before this rule:

     width  links need  links get  hidden inside the scroller
     768    287px       204px      Conversations AND FAQ   (RU: Вопросы)
     844    292px       271px      FAQ                     (RU: Вопросы)
     1024   429px       429px      none - fits exactly

   The links live in `.fcx`, the same horizontally-scrolling container the filmstrips use,
   set to flex:1 1 auto. So they do not overflow the page and no probe sees a fault: they
   scroll out of sight inside their own box, land underneath the language switcher, and
   `elementFromPoint` returns the nav rather than the link. Unreachable, with nothing on
   screen saying the nav scrolls. 768 is tablet portrait and 844 is EVERY iPhone in
   landscape, so this is not an edge case.

   Below 760 the links are hidden outright (above) and the footer carries them. Between 761
   and 1023 they are shown, so they have to FIT. The wordmark is 183px against a worst-case
   83px shortfall, and hiding it is the same call the 520 rule already makes for the same
   reason: the mug is the brand mark, the nav items are the navigation. Restored at 1024,
   where the full lockup and all four links coexist. */
@media (min-width: 521px) and (max-width: 1023px){
  header nav > a[href="#top"] > span{
    position:absolute;width:1px;height:1px;overflow:hidden;
    clip-path:inset(50%);white-space:nowrap}
}

/* The header is sticky at the top, so in landscape it sits under the notch on
   an iPhone. Padding, not margin, so the bar's own background still fills the
   inset rather than leaving a stripe of page showing through. */
header nav{
  padding-left:max(clamp(16px,3vw,36px),env(safe-area-inset-left)) !important;
  padding-right:max(clamp(16px,3vw,36px),env(safe-area-inset-right)) !important}

/* iPhone landscape: the hero's font-size is a pure vw-clamp, and vw does not know the
   viewport is only ~400px TALL. Measured on a real iPhone 17 Pro Simulator, landscape,
   26 Aug 2026: h1 alone computed to 80px, and the primary CTA ("Save my chair") sat at
   y:507 in a 402px-tall viewport - fully below the fold on first load, reachable only by
   scrolling. Verified in the browser, not assumed from the CSS: getBoundingClientRect()
   on both the paragraph and the CTA before and after this fix.

   Scoped to short-and-wide viewports specifically (max-height, not max-width) so portrait
   phones and real tablets are untouched - this is a landscape-phone problem only. */
@media (max-height: 500px) and (orientation: landscape){
  .fc-nav{height:44px !important}
  /* The hero wrapper's own top padding was the largest single offender - clamp(24px,3.4vw,46px)
     computes to ~30px at a typical landscape width, on top of everything else below it. */
  section:has(h1) > div{padding-top:4px !important}
  section:has(h1) [style*="margin-bottom: clamp(14px"]{margin-bottom:4px !important}
  h1{font-size:clamp(20px,4.6vw,36px) !important;
     margin-bottom:4px !important}
  section:has(h1) p{
    max-width:none !important;
    margin-bottom:4px !important}
}

/* ------------------------------------------ per-item share, quotes + archive
   Injected by site.js, so it exists only where JavaScript ran and never leaves
   a dead control behind. Deliberately quiet: this sits beside somebody's words,
   and a loud button next to a testimonial reads as a widget rather than as an
   offer. It comes up on hover and focus, and stays permanently visible on touch,
   where there is no hover to reveal it. */
.fc-item-share{
  display:inline-block;margin-top:10px;padding:7px 12px;min-height:32px;
  background:transparent;border:1px solid currentColor;color:inherit;
  font-family:'PT Mono',monospace;font-size:10.5px;letter-spacing:.09em;
  text-transform:uppercase;cursor:pointer;opacity:.42}
.fc-item-share:hover,.fc-item-share:focus-visible{opacity:1}
/* 44px only where a finger is doing the pointing. A mouse does not need it, and
   a 44px control beside every testimonial turns a quiet offer into furniture. */
@media (hover:none){.fc-item-share{opacity:.7;min-height:44px;padding:11px 14px}}

/* The archive sits on the cream panel where `currentColor` is nearly black; the
   quote wall is on ink. Both inherit correctly, so no per-section colour is set
   here on purpose - one rule, and it cannot drift from either background. */

/* -------------------------------------------- the invitation on arrival
   Shown only to someone who followed a shared link, next to the thing they came
   to read. Inherits colour so it works on the ink quote wall and the cream
   archive without a second rule that could drift from either. Kept quiet: it is
   an offer beside somebody's words, not a banner. */
.fc-arrival{
  display:flex;flex-wrap:wrap;align-items:center;gap:12px 16px;
  margin:18px 0 4px;padding:14px 16px;
  border:1px solid currentColor;background:rgba(242,214,77,.10)}
.fc-arrival-line{margin:0;font-size:14.5px;line-height:1.5;flex:1 1 16ch}
.fc-arrival-cta{
  display:inline-flex;align-items:center;min-height:44px;padding:0 18px;
  background:rgb(168,60,28);color:rgb(244,242,236);text-decoration:none;
  font-family:Unbounded,sans-serif;font-weight:800;font-size:12px;
  text-transform:uppercase;letter-spacing:.02em;white-space:nowrap}
@media (prefers-reduced-motion:no-preference){
  .fc-arrival{animation:fcArrive 260ms cubic-bezier(.16,1,.3,1) both}}
@keyframes fcArrive{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* ------------------------------------------------ bring someone by name
   Sits under the share buttons. Quiet by design: it is an offer, not a signup
   form, and it should not compete with the chair CTA. */
.fc-invite{margin-top:16px;padding-top:16px;border-top:1px solid rgba(16,16,16,.18)}
.fc-invite-lead{margin:0 0 10px;font-size:14px;line-height:1.5;color:rgb(74,70,61);max-width:46ch}
.fc-invite-fields{display:flex;flex-wrap:wrap;gap:8px}
.fc-invite-fields input{
  flex:1 1 190px;min-width:0;padding:12px 13px;font-size:15px;
  border:1px solid rgba(16,16,16,.3);background:rgb(244,242,236)}
.fc-invite-send{
  flex:0 0 auto;min-height:44px;padding:0 20px;border:none;cursor:pointer;
  background:rgb(28,26,22);color:rgb(242,214,77);
  font-family:Unbounded,sans-serif;font-weight:800;font-size:12px;
  text-transform:uppercase;letter-spacing:.02em}
.fc-invite-send[disabled]{opacity:.6;cursor:default}

/* ARCHIVE "ADD A MEMORY": THE YEAR FIELD MUST GIVE WAY, NOT THE BUTTON.
   1 Sep 2026, found by a responsive pass at 320 and nowhere else - every other
   width in the house list was clean, which is why it survived this long.

   The row is `display:flex; gap:10px` holding a 170px year field at
   `flex: 0 0 auto` and a Submit button at `flex: 1 1 auto`. 170 + 10 + the
   button's ~110px min-content is 290, inside a 250px parent, so the button's
   right edge was clipped by 5px. The page did not scroll horizontally - an
   ancestor's `overflow-x: hidden` swallowed it - which is exactly why no probe
   caught it and the contact sheet looked fine.

   `!important` because this is a Claude Design export: every element carries its
   own `style`, so an unmarked rule loses silently. Selector is structural for
   the same reason - there is one numeric input per page and it is this one. */
@media (max-width: 360px) {
  input[inputmode="numeric"] {
    width: auto !important;
    flex: 1 1 auto !important;
    min-width: 0 !important;
  }
}


/* ============================================================== MOTION (18 Sep 2026)
   One table on a Thursday morning: people arrive, sit down, pass things across. So the page
   moves the same way, and each section enters as what it is instead of all 59 sharing one fade.
   site.js reads the structure and names a variant on each [data-reveal] (data-rv); nothing here
   depends on the language, so /en/ and /ru/ move identically from one code path.
   transform, opacity and clip-path only. Essential content is in the DOM and readable with JS off
   (reveal-on is only set once JS has measured the viewport); reduced motion keeps every state and
   drops the travel - see the block near the top. */
:root{
  --fc-ease-out:cubic-bezier(.23,1,.32,1);      /* entering: fast off the mark, long settle */
  --fc-ease-io:cubic-bezier(.77,0,.175,1);      /* moving on screen */
  --fc-press:160ms; --fc-ui:220ms; --fc-enter:560ms; --fc-stagger:55ms;
}
@media (prefers-reduced-motion:no-preference){
  /* Headings rise into a window from their own baseline. The window is widened a little past
     the box so descenders and the tight .92 line-height never get cropped once it is open. */
  html.reveal-on [data-rv=wipe]{opacity:1;transform:translateY(.35em);
    clip-path:inset(100% -.2em -.35em -.2em);transition-duration:.72s}
  html.reveal-on [data-rv=wipe].is-in{transform:none;clip-path:inset(-.2em -.2em -.35em -.2em)}

  /* The four steps: each card lands, then a line is drawn across its top in turn - a running
     order being written down. The line fades once drawn, so nothing is left behind in a colour
     the design did not have. */
  html.reveal-on [data-rv=step]{position:relative!important}
  html.reveal-on [data-rv=step]::after{content:"";position:absolute;left:0;right:0;top:-1px;height:2px;
    background:rgb(242,214,77);transform:scaleX(0);transform-origin:0 50%;opacity:0;pointer-events:none}
  html.reveal-on [data-rv=step].is-in::after{animation:fcDraw 1.25s var(--fc-ease-out) both;
    animation-delay:calc(var(--rv-i,0) * 140ms + 120ms)}

  /* The twelve asks are dealt round the table, left to right, one after another. */
  html.reveal-on [data-rv=deal]{transform:translateX(-22px)}

  /* Voices are passed across: alternate sides, a hand's tilt, settling flat. */
  html.reveal-on [data-rv=pass-l]{transform:translate(-26px,10px) rotate(-1.2deg);transform-origin:50% 100%}
  html.reveal-on [data-rv=pass-r]{transform:translate(26px,10px) rotate(1.2deg);transform-origin:50% 100%}
  html.reveal-on [data-rv=pass-l].is-in,html.reveal-on [data-rv=pass-r].is-in{transition-duration:.66s}
}
@keyframes fcDraw{0%{transform:scaleX(0);opacity:1}62%{transform:scaleX(1);opacity:1}100%{transform:scaleX(1);opacity:0}}

/* Feedback on the asks, only where a real pointer hovers - on a phone a tap would stick it. */
@media (hover:hover) and (pointer:fine){
  /* html.reveal-on prefix on purpose: the base .is-in rule is (0,3,1) and would out-rank a bare selector. */
  html.reveal-on [data-rv=deal].rv-done{transition:transform var(--fc-ui) var(--fc-ease-out)}
  html.reveal-on [data-rv=deal].rv-done:hover{transform:translateX(6px)}
}

/* THE FOCAL MOMENT: the chairs. When the live count arrives, twelve chairs set themselves out in
   the tile, the taken ones filling, and the number counts up to what is left. It plays once, on
   arrival, and it is the one number on the page that should make someone act. The real text is
   in the DOM throughout (.fc-vh); the counting numerals and the chairs are aria-hidden. */
.fc-vh{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.fc-count{font-variant-numeric:tabular-nums}
.fc-pips{display:flex;flex-wrap:wrap;gap:4px;margin-top:10px;max-width:168px}
.fc-pip{width:9px;height:12px;border:1.5px solid currentColor;border-radius:2px 2px 1px 1px;box-sizing:border-box}
.fc-pip.is-taken{background:currentColor;opacity:.38}
@media (prefers-reduced-motion:no-preference){
  .fc-pips.is-playing .fc-pip{animation:fcPip 420ms var(--fc-ease-out) both;animation-delay:calc(var(--p) * 45ms)}
}
@keyframes fcPip{from{opacity:0;transform:translateY(7px) scale(.82)}}

.fcPartnerTrack.is-off{animation-play-state:paused}

/* Russian display type hyphenates rather than being cut (18 Sep 2026). "Здесь вы найдёте
   единомышленников и друзей" went in on 16 Sep and its long word ran 130-224px past the edge at
   every phone width, while the gate's layout probe stayed green - the box fitted, the word inside
   it did not. House rule: hyphenate, never shrink (RULES.md, "Measure BOTH languages"). <html
   lang="ru"> hands the browser the dictionary. The hero wordmark is excluded: a hyphen through
   "ДВЕНАДЦАТЬ" would be worse than the problem. overflow-wrap is the backstop for a word with no
   hyphenation point. */
html[lang=ru] [style*="Unbounded"]:not(h1){-webkit-hyphens:auto;hyphens:auto;overflow-wrap:break-word;
  /* only words of 12+ letters: "СТОЛЬ-КО" was hyphenated for a neater rag it did not need */
  hyphenate-limit-chars:12 5 5}

/* Sticky that actually sticks (18 Sep 2026). The export's root wrapper carries an inline
   overflow-x:hidden, which makes it a scroll container, so the sticky header pinned to the
   WRAPPER and scrolled away with the page (sticky-check: header at -3000px after 3000px of
   scroll). clip crops exactly the same and creates no scroll container. Scoped to the wrapper
   around the nav only - the archive carousel must keep its own overflow. */
[style*="overflow-x: hidden"]:has(.fc-nav){overflow-x:clip!important}

/* The estate's top bar (#ydnav, web-toolkit/tools/estate-nav, 18 Sep 2026) is sticky at top:0 too, so our own
   header has to stop underneath it or its top 51px hide behind the bar once the page scrolls. The bar measures
   and publishes its own height as --ydnav-h on <html> (estate-nav.js); 51px is what it measured on 18 Sep. */
body:has(#ydnav) header:has(.fc-nav){top:var(--ydnav-h,51px)!important}

/* The Conversation section's left column is sticky at 96px - our header's 66px plus air. Two fixes (18 Sep 2026):
   with the estate bar above the header it has to add the bar's height, or its heading hides 22px under the header;
   and in ONE column (the grid is repeat(auto-fit, minmax(min(100%,300px),1fr)): one column at 680px and below,
   measured) a sticky column just sits on top of the feed scrolling beneath it - on production before the bar too -
   so there it does not stick at all. */
[style*="position: sticky; top: 96px"]{top:calc(var(--ydnav-h,0px) + 96px)!important}
@media (max-width: 682px){[style*="position: sticky; top: 96px"]{position:static!important}}

/* Every in-page jump (the nav's FORMAT/ARCHIVE/..., "Take a chair", scrollIntoView in site.js) was tuned for our header
   alone. The estate bar adds its height on top, so without this a phone lands the booking form's heading 41px under
   the bars (measured 18 Sep 2026: heading at 77px, bars end at 118). Shifting every stop by the bar's own height keeps
   each one exactly where it landed before the bar existed. */
html{scroll-padding-top:var(--ydnav-h,0px)}

/* The booking form's bot trap (22 Sep 2026): in flow, zero height, invisible, out of the tab order. Never
   position:absolute - the gate's escaped-absolute probe would rightly call that an escaped element. */
.fc-hp{height:0!important;overflow:hidden!important;opacity:0!important;pointer-events:none!important;margin:0!important;padding:0!important}

/* Landscape phones (22 Sep 2026). The hero is a two-column grid with align-items:end, so the words sit level
   with the photo's lower edge. At 874x402, under the estate bar and our header, that put "Save my chair" at
   396px of a 402px screen in English and fully off it in Russian. On a short landscape screen only, the words
   sit at the top of their column instead; upright phones, tablets and desktops keep the design as it was. */
@media (orientation: landscape) and (max-height: 500px){
  [style*="minmax(min(100%, 290px), 1fr)"][style*="align-items: end"]{align-items:start!important}
}
