/* =================================================================
   ELEMENT Barbershop — HERO EXPERIMENT
   "Bauhaus Ausstellung poster": hard rules, stacked display type,
   framed geometric stage. Mobile-first.
   ================================================================= */

/* ---------- Design tokens ---------- */
:root {
  --cream:  #F1EFE9;
  --ink:    #111111;
  --blue:   #1B4FD8;
  --red:    #E63329;
  --yellow: #F5C200;
  --white:  #FFFFFF;

  /* Inter Tight — Hanken Grotesk lacks base Cyrillic (U+0410–044F), so the
     Bulgarian UI text fell back to system fonts; Inter Tight covers both. */
  --font: "Inter Tight", system-ui, -apple-system, "Segoe UI", sans-serif;

  --gutter: clamp(1.1rem, 5vw, 1.6rem);
  --rule: 2px solid var(--ink);
  --rule-thin: 1.5px solid var(--ink);
  --header-h: 4rem;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* WebView font-boosting guard (see v4 notes) */
.hero__title, .hero__line, .cta__text, .bookbar__text {
  max-height: 1000000px;
}

body {
  font-family: var(--font);
  color: var(--ink);
  background: #e7e4dc;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; padding: 0; margin: 0; }
button { font: inherit; color: inherit; border: 0; background: none; cursor: pointer; }

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

.skip-link {
  position: absolute;
  left: 50%;
  top: -100%;
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--white);
  padding: 0.6rem 1.1rem;
  z-index: 100;
  transition: top 0.2s;
}
.skip-link:focus { top: 0; }

/* ---------- Phone frame ---------- */
.phone {
  width: 100%;
  max-width: 30rem;
  min-height: 100vh;
  min-height: 100svh;
  margin-inline: auto;
  /* clean cream — the 3% drafting-paper grid that lived here was
     removed 2026-07-14 (user call): all grid texture now belongs to the
     stage alone, which reads as THE designed canvas against flat paper
     (revert: _backups/pre-grid-removal_2026-07-14) */
  background-color: var(--cream);
  overflow: clip;
  position: relative;
  display: flex;
  flex-direction: column;
}

/* =================================================================
   HEADER — ruled band, logo + boxed burger
   ================================================================= */
.header {
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  height: var(--header-h);
  border-bottom: var(--rule);
}

.logo {
  display: flex;
  align-items: center;
  padding-inline: var(--gutter);
}

.logo__mark { width: clamp(9.5rem, 46vw, 12rem); height: auto; }

/* burger — solid ink cell, cream lines */
.burger {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 6px;
  width: clamp(3.6rem, 16vw, 4.4rem);
  border-left: var(--rule);
  background: var(--ink);
}
.burger span {
  display: block;
  width: 1.5rem;
  height: 2.5px;
  background: var(--white);
}
/* shorter bottom line, left-aligned with the others — branded burger;
   the margin re-centres the group so the left edges stay flush */
.burger span:last-child {
  width: 0.9rem;
  margin-right: 0.6rem;
}

/* =================================================================
   HERO
   ================================================================= */
main {
  display: flex;
  flex-direction: column;
  flex: 1;
}

/* the hero owns the first viewport: header + hero = 100svh; the poster
   card (flex: 1) absorbs whatever height is left over.
   The width-based cap stops the stage stretching into a tower on
   freak-tall viewports (foldable covers, half-snapped desktop windows):
   no-op on 360–430 phones (aspect ≤ ~2.16), engages past ~2.05× width —
   there the marquee band simply peeks into the first viewport. */
.hero {
  display: flex;
  flex-direction: column;
  min-height: min(calc(100svh - var(--header-h)),
                  calc(min(100vw, 30rem) * 2.05));
  position: relative;
}

/* ---------- plate row: index no. / place / shapes ---------- */
.hero__plate {
  display: flex;
  align-items: center;
  /* both clamps hit their max by ~360px — identical to the approved
     phone look; below that they trade size for a one-line plate */
  gap: clamp(0.5rem, 4vw, 0.9rem);
  padding: 0.55rem var(--gutter);
  border-bottom: var(--rule-thin);
  font-size: clamp(0.64rem, 3.5vw, 0.75rem);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  /* plate stamps are single-line by design — "№ 01" must not break
     after the № either */
  white-space: nowrap;
}

.hero__plate-no { color: var(--red); }

/* thin rule between the plate № and the place name — same ink voice as
   the header/plate rules; ::before keeps the markup untouched */
.hero__plate-place {
  display: flex;
  align-items: center;
  gap: clamp(0.5rem, 4vw, 0.9rem);
  /* the place name is a plate stamp — it must never break to two lines */
  white-space: nowrap;
}
.hero__plate-place::before {
  content: "";
  width: 1.5px;
  height: 1em;
  background: var(--ink);
}

.hero__plate-shapes {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: none;      /* fixed-size geometry never squishes */
}
.ps { display: block; }
.ps--circle { width: 0.625rem; height: 0.625rem; border-radius: 50%; background: var(--blue); }
.ps--square { width: 0.625rem; height: 0.625rem; background: var(--yellow); }
.ps--tri {
  width: 0.68rem; height: 0.62rem;
  background: var(--red);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

/* ---------- headline: stacked poster caps ---------- */
.hero__title {
  position: relative;
  padding: clamp(0.9rem, 4vw, 1.3rem) var(--gutter) clamp(0.2rem, 1.1vw, 0.5rem);
  font-weight: 900;
  font-size: clamp(1.875rem, 10.5vw, 2.875rem);
  /* 1.03 (was 0.98): one notch of air between the lines — the stack
     still reads as one block, but the lines stop touching (2026-07-14).
     Costs ~10px total; the flex stage absorbs it on every card above
     its floor, so the CTA's fold position is unchanged */
  line-height: 1.03;
  letter-spacing: -0.025em;
  text-transform: uppercase;
}

/* the brand word leads the stack — one step up, Bauhaus poster
   hierarchy: the word that IS the shop name outweighs its neighbours.
   Scoped to the hero title; .t-red elsewhere keeps its line's size. */
.hero__title .t-red { font-size: 1.1em; }

/* thin vertical rule beside the headline, at the right content edge */
.hero__rail {
  position: absolute;
  right: calc(var(--gutter) + 3px);
  /* run cap-height → baseline of the type, not box → box: title padding
     + 0.15em (was 0.13 — the 0.127em Inter Tight cap inset was measured
     at line-height 0.98; the 1.03 leading adds 0.025em of half-leading
     above the cap and below the baseline, same constant both ends) */
  top: calc(clamp(0.9rem, 4vw, 1.3rem) + 0.15em);
  bottom: calc(clamp(0.2rem, 1.1vw, 0.5rem) + 0.15em);
  width: 2px;
  background: var(--ink);
}

.hero__line { display: block; overflow: hidden; }
.hero__line .reveal { display: block; }

.hero__title em { font-style: normal; }

.t-red { color: var(--red); }

/* outlined word — hollow: paper fill over a 3.2px stroke leaves ~1.6px
   visible. A truly transparent fill exposes seams where Inter Tight's
   glyph outlines self-intersect (e.g. the R), so paper fill covers them. */
.t-outline {
  color: var(--cream);
  -webkit-text-stroke: 3.2px var(--ink);
  paint-order: stroke fill;
  /* the stroke bleeds 1.6px out of each glyph edge, eating the word
     space from both sides — give it back so "your style" separates
     exactly like the solid lines */
  word-spacing: 0.08em;
}
/* no text-stroke support → cream fill would vanish on the cream page;
   fall back to solid ink */
@supports not (-webkit-text-stroke: 1px #000) {
  .t-outline { color: var(--ink); }
}

/* full stop as a yellow square — geometry instead of punctuation.
   0.21em (was 0.17): the outline eats a fixed 2px, so at the old size
   the yellow fill nearly vanished; the bump gives it back its accent
   presence while still reading as a period, not a block. */
.t-dot {
  display: inline-block;
  width: 0.21em;
  height: 0.21em;
  margin-left: 0.08em;
  background: var(--yellow);
  outline: 2px solid var(--ink);
  outline-offset: -1px;
}

/* ---------- rating row: star · score · count · Google ---------- */
.hero__rating {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 3rem;                 /* 48px tap target */
  padding: 0.2rem var(--gutter);
  font-size: 1.05rem;
  /* breathing room so the headline's baseline isn't crowding the stars */
  margin-top: 0.5rem;
  /* pull the poster card up 6px; z-index keeps the full 48px hit area
     clickable over the (non-interactive) card edge */
  position: relative;
  z-index: 1;
  margin-bottom: -6px;
}
.hero__rating strong { font-weight: 900; }

.hero__rating-stars {
  display: flex;
  gap: 0.16rem;
}

.hero__rating-star {
  width: 0.98rem;
  height: 0.98rem;
  fill: var(--yellow);
  stroke: var(--ink);
  stroke-width: 1.4;
}

.hero__rating-div {
  width: 1.5px;
  height: 1.05rem;
  background: rgba(17, 17, 17, 0.3);
}

.hero__rating-count {
  font-weight: 600;
  font-size: 0.85rem;
  color: #4a4a48;
}

.hero__rating-count b { font-weight: 800; color: var(--ink); }

/* ---------- poster card: framed white stage, geometry + cut-out ---------- */
.stage {
  position: relative;
  margin-inline: var(--gutter);
  border: var(--rule);
  /* the "designed canvas": the page's ONLY grid since the 3% page-wide
     tissue was removed (2026-07-14) — a fine 20px blueprint sheet on
     white that marks the stage as the drafted object against the flat
     cream paper. The 6px origin offset survives from the two-sheet era;
     it keeps the grid from registering with the frame rules. */
  background-color: var(--white);
  background-image:
    linear-gradient(to right, rgba(17, 17, 17, 0.06) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(17, 17, 17, 0.06) 1px, transparent 1px);
  background-size: 20px 20px;
  background-position: 6px 6px;
  flex: 1;
  /* height floor: 17.5rem on ≥ ~667px-tall viewports (unchanged), then
     gives ground on short screens so the CTA stays above the fold;
     23.5rem ≈ header + plate + title + rating + CTA + util overhead */
  min-height: clamp(13.5rem, 100svh - 23.5rem, 17.5rem);
  /* visible only so the blue square can straddle the left rule — the
     cut-out is contained by its own clip-path, everything else stays
     inside the frame */
  overflow: visible;
}

/* yellow sun circle — upper-center */
.stage__circle {
  position: absolute;
  top: 4%;
  left: 11%;
  width: 78%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--yellow);
}

/* dot-grid motif, upper-left — fixed 14px inset, mirrored by the brand strip */
.stage__dots {
  position: absolute;
  top: 14px;
  left: 14px;
  width: 4.6rem;
  height: 4.6rem;
  background: radial-gradient(circle, var(--ink) 1.4px, transparent 1.9px) 0 0 / 1.02rem 1.02rem;
}

/* blue square, lower-left — collage layer: overlaps the cut-out so it
   stays fully visible and masks the raster's left cut edge */
.stage__square {
  position: absolute;
  /* straddles the card's left rule — hangs into the cream margin; its
     right edge still covers the cape raster's left cut line */
  left: -4.5%;
  /* 21% (was 26%): clears the circle's lower arc — no tangent "kiss" —
     while still overlapping the cape shoulder for the collage interlock */
  bottom: 21%;
  width: 20%;
  aspect-ratio: 1;
  background: var(--blue);
  z-index: 3;
}

/* red right-triangle, clipped into the bottom-right corner — collage
   layer, same role on the right side */
.stage__tri {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 38%;
  aspect-ratio: 1;
  background: var(--red);
  clip-path: polygon(100% 0, 100% 100%, 0 100%);
  z-index: 3;
}

/* grayscale cut-out, anchored bottom-center, scales with the card.
   Dropped 3% below the card edge: grounds the figure and lowers the
   raster's side cut lines behind the square/triangle. The element
   shrink-wraps the raster (height + auto width) so the side fade
   aligns with the actual cape edges. */
.stage__cutout {
  position: absolute;
  left: 50%;
  /* grounded 3% below the frame line via translate, and clipped by the
     SAME 3% — both resolve against the element's own height, so the
     overhang and the cut cancel exactly at every card ratio and the
     cape's bottom edge always lands flush on the rule's inner edge
     (the stage doesn't clip — the square needs to hang out). The old
     -3%-of-stage bottom + 3.2%-of-element clip pair drifted whenever
     the height % was retuned and printed a sliver over the ink rule. */
  bottom: 0;
  clip-path: inset(0 0 3% 0);
  transform: translate(-50%, 3%);
  /* 88% (stepped 94 → 91 → 88, 2026-07-14): the re-cropped raster is
     trimmed tight to the hair (the old file wasted 18.6% of its height
     on transparent headroom), so the original 94 printed the figure
     wall-to-wall and the poster lost its air. 88 is the sweet spot —
     it meets the 88% width cap, so the figure holds a steady ~86% of
     the stage on EVERY card ratio (~40px under the arc at 360×740),
     still ~15% larger than the old headroom-padded raster */
  height: 88%;
  width: auto;
  /* cap: on tall cards the raster would otherwise span edge to edge —
     keep white gutters so the figure stays inside the circle */
  max-width: 88%;
  object-fit: contain;
  object-position: bottom center;
  z-index: 2;
  filter: grayscale(1) contrast(1.05);
  /* asymmetric dissolve: the left fade melts the raster's left crop
     line where it runs on open ground below the blue square. 5% (was
     9%): the enlarged figure pushed the dissolve zone onto the yellow
     sun, and the wide fade read as translucency ON the cape — half the
     width still kills the hard line without the visible smudge. The
     right fade stays at 97.5%: only needed on extreme-wide cards
     (landscape), where the red triangle can't reach the right cut */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 5%, #000 97.5%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 5%, #000 97.5%, transparent);
}

/* vertical brand text along the inner right edge — decoration.
   14px top/right inset, mirroring the dot grid's 14px top/left. */
.stage__brand {
  position: absolute;
  top: 14px;
  right: 14px;
  /* below the square/tri collage layer: on short cards the strip's tail
     slips behind the red triangle instead of printing over it */
  z-index: 2;
  writing-mode: vertical-rl;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--ink);
}
/* ---------- stage self-awareness ----------
   The stage's internals scale against different axes (circle by width,
   cut-out by height), so on stretched or squashed cards they drift
   apart. The stage is an inline-size container (its height is flex-
   derived — indefinite — so a size container's cqh would resolve to 0);
   the height axis is read via % (height-relative inside `bottom`) and
   via 100svh − 23.5rem, the stage's own min-height formula. Every
   expression resolves to the current values at the approved 360–430
   phone sizes — no visual change there. Non-supporting browsers keep
   the plain top-anchored layout. */
@supports (width: 1cqw) {
  .stage { container-type: inline-size; }

  /* bottom-anchored sun: rides with the figure when the card grows
     taller instead of floating up away from the head.
     · diameter: width-driven as before, height-capped on squat cards
       (88% of the stage's min-height floor)
     · 34% = the exact position the old `top: 4%` produced at the
       reference card ratio (~1.26) — identical on approved phones
     · the max() arm keeps ≥ 4% top clearance on short cards
     · the 9rem floor keeps the sun alive on landscape phones, where
       88svh − 20.7rem goes negative and width would clamp to 0 —
       no-op on every portrait size (their svh arm is always larger) */
  .stage__circle {
    --d: max(9rem, min(78cqw, 88svh - 20.7rem));
    width: var(--d);
    top: auto;
    bottom: min(34%, max(96% - var(--d), 4%));
  }

  /* the vertical brand strip runs ~17× its font-size; fit it into the
     free column between its 14px top inset and the red triangle's
     hypotenuse (the triangle is 38% of the stage width tall, anchored
     bottom-right) with an 8px gap, so it never prints into — or
     vanishes behind — the shape. Uses the stage's own height proxy
     (100svh − 23.5rem, ~6px conservative). On tall cards it saturates
     the 0.6875rem max — identical to the approved phone look; only on
     squat cards does it step down to stay clear. */
  .stage__brand {
    font-size: clamp(0.42rem, (100svh - 23.5rem - 38cqw - 22px) / 17, 0.6875rem);
  }
}

/* margin-inline runs along the (vertical) inline axis — equal space each side */
.stage__brand-sq {
  display: inline-block;
  width: 0.55em;
  height: 0.55em;
  background: var(--yellow);
  margin-inline: 0.5em;
}

/* ---------- actions: full-width booking, below the card ---------- */
.hero__actions {
  display: flex;
  margin-top: 8px;
  padding: 0 var(--gutter);
}

/* split cell: black label + red arrow block, divided like the poster grid */
.cta {
  flex: 1;
  display: flex;
  align-items: stretch;
  min-height: 4rem;
  background: var(--ink);
  color: var(--white);
  font-size: clamp(1.0625rem, 4.6vw, 1.3125rem);
  font-weight: 900;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  /* resting hard offset shadow (2026-07-14, was crisp/none): the button
     joins the "physical object" class the quote/collage cards already
     occupy — a block laid on the paper, never a soft blur. The press
     now SEATS the block into the page instead of conjuring a shadow */
  box-shadow: 5px 6px 0 rgba(17, 17, 17, 0.16);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

/* desktop: lifts further toward the light */
.cta:hover, .cta:focus-visible {
  transform: translate(-2px, -3px);
  box-shadow: 8px 10px 0 rgba(17, 17, 17, 0.16);
}
/* the payload for THIS phone-first design: the tap seats the block —
   it travels the shadow's offset and lands flat on the paper */
.cta:active {
  transform: translate(4px, 5px);
  box-shadow: 1px 1px 0 rgba(17, 17, 17, 0.14);
  transition-duration: 0.05s;
}
/* motion-averse users still get the shadow feedback, minus the shift */
@media (prefers-reduced-motion: reduce) {
  .cta:hover, .cta:focus-visible, .cta:active { transform: none; }
}

.cta__text {
  flex: 1;                   /* box spans exactly the ink area (up to the red cell) */
  display: flex;
  flex-direction: column;    /* label over (optional) microcopy; single-label CTAs unaffected */
  align-items: center;
  justify-content: center;   /* so symmetric padding centres the label in the black */
  gap: 0.3rem;
  /* tight block padding + set-solid line so label + microline together
     stay under the 4rem min-height — the button must not grow */
  line-height: 1.15;
  padding: 0.55rem 1.25rem;
}

/* benefit microline under the label — fits inside the 4rem cell the
   button already pays for, so it costs zero height (2026-07-14) */
.cta__micro {
  /* fluid: full 0.56rem from ~360px up, eases down on narrower phones —
     at 320 the line needs ≤ 169px or its nowrap min-width squeezes the
     red arrow cell (flex steals from the neighbour before overflowing) */
  font-size: clamp(0.48rem, 2.5vw, 0.56rem);
  font-weight: 700;
  letter-spacing: 0.2em;  /* 0.22 left a 0.3px fit margin at 320 — too fragile across font renderers */
  /* 0.92 (was 0.8, was 0.72 — both passed AA): at 9px on dim OLEDs the
     muted blends read muddy; near-full cream keeps the line crisp while
     the 2× size gap to the label carries the hierarchy on its own */
  color: rgba(241, 239, 233, 0.92);
  white-space: nowrap;
}

.cta__cell {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 4.75rem;
  flex: none;   /* grammar cell — the microline's nowrap min-width must never squeeze it */
  background: var(--red);
}

.cta__arrow {
  width: 1.55rem;
  height: 1.55rem;
  stroke: currentColor;
  stroke-width: 2.2;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.15s;
}
.cta:hover .cta__arrow, .cta:focus-visible .cta__arrow, .cta:active .cta__arrow { transform: translateX(6px); }

/* ---------- utility line: the address, meta-strip voice ---------- */
.hero__util {
  padding: 8px var(--gutter) 0.9rem;   /* 8px — same gap as card → CTA */
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  white-space: nowrap;
  text-align: center;
}
.hero__util a {
  display: inline-block;
  /* padding grows the tap target to ≥48px without moving the line */
  padding: 1.05rem 0.3rem;
  margin: -1.05rem -0.3rem;
}
.hero__util a b { font-weight: 700; color: var(--red); }

/* the hours moved out of this line (2026-07-14 — they live in the
   contact plate, where the open/closed logic backs them up): a lone
   address fits every width at full tracking, so the old narrow-phone
   tracking ladder and the yellow separator square went with them */

/* inline glyphs in the utility line — same stroke voice as the contact
   icons; inline-block overrides the global block reset for svg */
.hero__util-ic {
  display: inline-block;
  width: 1.05em;
  height: 1.05em;
  vertical-align: -0.22em;
  fill: none;
  stroke: var(--ink);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* =================================================================
   SERVICES — ruled price index
   ================================================================= */
.hero__plate--section {
  border-top: var(--rule);
}

.sec-title {
  padding: clamp(1.2rem, 5vw, 1.7rem) var(--gutter) clamp(1rem, 4.2vw, 1.4rem);
  font-weight: 900;
  font-size: clamp(1.75rem, 8.2vw, 2.4rem);
  line-height: 1.02;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}

.t-dot--blue { background: var(--blue); }

/* stacked featured title — hero echo (red / outline / solid) */
.sec-title { position: relative; }
.sec-title__line { display: block; position: relative; z-index: 1; }
.sec-title em { font-style: normal; }
/* hero's 3.2px stroke is tuned for its larger type — scale down here */
.sec-title .t-outline { -webkit-text-stroke-width: 2.6px; }

/* thin ink rail beside the featured title — the same device as the
   hero's headline rail, so "display stack + rail" reads as the site's
   headline grammar. Cap-height → baseline run via the hero's 0.13em
   constant, against this title's own paddings. */
.sec-title__rail {
  position: absolute;
  right: calc(var(--gutter) + 3px);
  top: calc(clamp(1.2rem, 5vw, 1.7rem) + 0.13em);
  bottom: calc(clamp(1rem, 4.2vw, 1.4rem) + 0.13em);
  width: 2px;
  background: var(--ink);
}

/* one beat of prose between the display type and the ledger */
.sec-intro {
  margin-top: -0.2rem;
  padding: 0 var(--gutter) clamp(1.1rem, 4.6vw, 1.5rem);
  max-width: 32ch;
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.5;
  color: #4a4a48;
}

/* no opening rule: rules in this ledger are SEPARATORS between rows
   (.price__row + .price__row), never caps — the list opens with air
   under the intro and closes on the next plate's own top rule */
.price {
  list-style: none;
  padding: 0;
}

.price__row + .price__row { border-top: var(--rule); }

/* ledger row: № lockup · rule · name/meta/desc · price */
.price__link {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: clamp(0.85rem, 4.2vw, 1.2rem);
  padding: clamp(1.65rem, 7.2vw, 2.1rem) var(--gutter);
  transition: background-color 0.15s;
}
.price__link:hover, .price__link:active { background: var(--white); }

/* tactile press — the whole row is the button, same press language as
   the CTA */
@media (prefers-reduced-motion: no-preference) {
  .price__link { transition: background-color 0.15s, transform 0.12s ease; }
  .price__link:active { transform: scale(0.985); }
}

/* № lockup: solid numeral → ghost echo tucked under it → shape pinning
   the ghost's corner — same outlined device as the team roster, now
   fully visible instead of hiding behind the text */
.price__no {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  font-size: clamp(2.05rem, 9.2vw, 2.5rem);
  font-weight: 900;
  line-height: 1;
  font-variant-numeric: tabular-nums;   /* 01/02/03 column stays optically rigid */
}
.price__ghost {
  margin: 0.12rem 0 0 0.4rem;
  color: transparent;
  -webkit-text-stroke: 2px rgba(17, 17, 17, 0.14);
}
.price__no .ps {
  /* third beat of the lockup: numeral → ghost → shape, cleanly stacked —
     overlap at this small scale read as misregistration, not collage */
  margin: 0.35rem 0 0 0.08rem;
  width: 1.35rem;
  height: 1.35rem;
}
.price__no .ps--tri { width: 1.45rem; height: 1.3rem; }

.price__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.34rem;
  min-width: 0;
  /* thin rule between the № lockup and the text — ruled-system voice */
  border-left: var(--rule-thin);
  padding-left: clamp(0.75rem, 3.2vw, 1rem);
}

.price__name {
  font-size: clamp(1.2rem, 5.8vw, 1.42rem);
  font-weight: 900;
  line-height: 1.12;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}
/* the brand word in red — the hero's red "element", same word same red,
   on all three rows. On the yellow slab it's 2.6:1 (below AA large-text
   3:1) — accepted as a brand call (user-ratified 2026-07-11): the word
   is quasi-decorative there ("COMBO" + stamp + aria-label carry the
   info) and red-on-yellow is period-correct Bauhaus.
   display:block stacks ELEMENT over the service word on every row at
   every width — a deliberate letterhead rhythm instead of the previous
   accidental wraps. */
.price__name-brand {
  display: block;
  color: var(--red);
}

/* inclusions only — the row's one geometric marker lives in the №
   lockup; inline flow so the line wraps like a sentence */
.price__meta {
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #4a4a48;
  line-height: 1.6;
}

.price__price {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.18rem;
  white-space: nowrap;
}

.price__eur {
  font-size: clamp(1.35rem, 6.2vw, 1.6rem);
  font-weight: 900;
  font-variant-numeric: tabular-nums;   /* prices align digit-for-digit */
}
.price__eur small {
  font-size: 0.52em;
  font-weight: 600;
}

.price__bgn {
  margin-top: 0.2rem;
  padding-top: 0.3rem;
  border-top: 1.5px solid rgba(17, 17, 17, 0.25);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: #4a4a48;
  font-variant-numeric: tabular-nums;
}
/* the whole row books on Fresha — quiet external-link mark, same voice
   as the roster and gallery rows */
.price__bgn b { font-weight: 800; color: var(--red); }

/* duration chip — an informational label, deliberately NOT in the 2px
   button grammar (thin muted border, quiet ink) so it never promises a
   tap it can't deliver */
.price__dur {
  margin-top: 0.2rem;
  padding: 0.16rem 0.45rem;
  border: 1.5px solid rgba(17, 17, 17, 0.45);
  color: #4a4a48;
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* signature row — yellow slab, ink chip */
.price__row--signature { background: var(--yellow); }
.price__row--signature .price__link:hover,
.price__row--signature .price__link:active { background: #ffd21f; }
.price__row--signature .price__meta,
.price__row--signature .price__bgn { color: rgba(17, 17, 17, 0.62); }
.price__row--signature .price__bgn { border-top-color: rgba(17, 17, 17, 0.35); }
.price__row--signature .price__bgn b { color: var(--ink); }   /* red fails on yellow */
.price__row--signature .price__ghost { -webkit-text-stroke-color: rgba(17, 17, 17, 0.18); }

/* the stamp — slight tilt sells it as pressed on, not typeset */
.price__sig {
  align-self: flex-start;
  margin-bottom: 0.18rem;
  padding: 0.18rem 0.5rem;
  background: var(--ink);
  color: var(--yellow);
  font-size: 0.56rem;
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  transform: rotate(-3deg);
  transform-origin: left bottom;
}

/* =================================================================
   GALLERY — Mondrian mosaic: ink joints, photo + primary cells
   ================================================================= */
.t-dot--red { background: var(--red); }

.mosaic {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(4, 1fr);
  gap: 2.5px;                 /* joints read as rules */
  background: var(--ink);     /* shows through the gaps */
  border-top: var(--rule);
  aspect-ratio: 3 / 3.6;
}

.mosaic__tile {
  position: relative;
  overflow: hidden;
  background: var(--white);
}

.mosaic__zoom {
  position: absolute;
  inset: 0;
  padding: 0;
  cursor: zoom-in;
}
.mosaic__zoom:focus-visible { outline-offset: -3px; }

.mosaic__tile img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* exhibit label — tiny ruled chip pinned in the tile corner */
.mosaic__chip {
  position: absolute;
  left: 0;
  bottom: 0;
  padding: 0.22rem 0.45rem;
  background: var(--white);
  border-top: 2px solid var(--ink);
  border-right: 2px solid var(--ink);
  font-size: 0.52rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink);
  white-space: nowrap;
}

.mosaic__tile--lead   { grid-column: 1 / 3; grid-row: 1 / 3; }
.mosaic__tile--studio { grid-column: 3 / 4; grid-row: 1 / 3; }
.mosaic__cell--red    { grid-column: 1 / 2; grid-row: 3 / 4; background: var(--red); }
.mosaic__tile--work   { grid-column: 2 / 4; grid-row: 3 / 5; }
.mosaic__tile--fade   { grid-column: 1 / 2; grid-row: 4 / 5; }

/* see-more row — ruled, like a price row */
.more {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.95rem var(--gutter);
  border-top: var(--rule);
  transition: background-color 0.15s;
}
.more:hover, .more:active { background: var(--white); }

.more__text {
  font-size: 0.95rem;
  font-weight: 800;
}

.more__handle {
  margin-left: auto;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #4a4a48;
}

.more__ne {
  font-size: 1rem;
  font-weight: 800;
  color: var(--red);
}

/* =================================================================
   ABOUT — collage plate: photo + overlapping promise card + book
   ================================================================= */
.collage {
  position: relative;
  margin-inline: var(--gutter);
  margin-bottom: 5.4rem;        /* room for the card hanging below */
  border: var(--rule);
}
.collage img { width: 100%; }

/* yellow quarter-circle, clipped to the frame corner */
.collage__quarter {
  position: absolute;
  top: 0;
  right: 0;
  width: clamp(3rem, 14vw, 3.8rem);
  aspect-ratio: 1;
  background: var(--yellow);
  border-left: var(--rule);
  border-bottom: var(--rule);
  border-radius: 0 0 0 100%;
}

/* the brand promise — hangs below the frame, only its top overlaps
   the photo so the sofa (the atmosphere) stays visible */
.collage__card {
  position: absolute;
  left: -0.55rem;
  bottom: -4.8rem;
  width: min(82%, 19rem);
  background: var(--white);
  border: var(--rule);
  border-left: 6px solid var(--red);
  padding: 0.85rem 0.95rem;
  font-size: 0.95rem;
  font-weight: 800;
  line-height: 1.4;
  box-shadow: 0.4rem 0.4rem 0 rgba(17, 17, 17, 0.12);
}

/* provenance footnote — one quiet ruled line */
.note {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem var(--gutter);
  border-top: var(--rule);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #4a4a48;
}
.note .ps { flex: none; }

/* three honest facts — ruled cells */
.facts {
  display: flex;
  border-top: var(--rule);
}

.facts__cell {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.85rem 0.35rem 0.85rem var(--gutter);
}
.facts__cell + .facts__cell { border-left: var(--rule); }

.facts__num {
  font-size: clamp(1.35rem, 6vw, 1.6rem);
  font-weight: 900;
  line-height: 1;
}
.facts__plus { color: var(--red); }

.facts__label {
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #4a4a48;
}

/* =================================================================
   TEAM — roster strips: B&W portrait, element color per barber
   ================================================================= */
.roster {
  border-top: var(--rule);
  border-bottom: var(--rule);
}
.roster__row + .roster__row { border-top: var(--rule); }

.roster__row--red    { --spine: var(--red);    --spine-text: var(--red); }
.roster__row--blue   { --spine: var(--blue);   --spine-text: var(--blue); }
.roster__row--yellow { --spine: var(--yellow); --spine-text: var(--ink); }

.roster__link {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: clamp(1rem, 4.5vw, 1.3rem);
  padding: 1rem var(--gutter);
  transition: background-color 0.15s;
  overflow: hidden;
}
.roster__link:hover, .roster__link:active { background: var(--white); }

/* B&W portrait on an offset element-color block */
.roster__photo {
  position: relative;
  width: clamp(6.6rem, 31vw, 8.2rem);
  aspect-ratio: 1;
  margin-right: 0.55rem;      /* room for the offset block */
  margin-bottom: 0.55rem;
}
.roster__photo::before {
  content: "";
  position: absolute;
  inset: 0;
  transform: translate(0.55rem, 0.55rem);
  background: var(--spine, var(--red));
}
.roster__photo img {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.05);
  border: var(--rule);
}

.roster__info {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.16rem;
  min-width: 0;
  position: relative;
  z-index: 1;
}

.roster__role {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--spine-text, var(--red));
}
.roster__role .ps { background: var(--spine, var(--red)); }

.roster__name {
  font-size: clamp(1.5rem, 7vw, 1.85rem);
  font-weight: 900;
  line-height: 1.02;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}

.roster__tag {
  font-size: 0.72rem;
  font-weight: 600;
  color: #4a4a48;
}

.roster__cta {
  margin-top: 0.45rem;
  padding-bottom: 0.15rem;
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--spine-text, var(--red));
  border-bottom: 2.5px solid var(--spine, var(--red));
}
.roster__cta b { font-weight: 800; }

/* giant plate index behind the row's right edge */
.roster__num {
  position: absolute;
  right: 0.4rem;
  bottom: -0.55rem;
  font-size: clamp(3.4rem, 16vw, 4.4rem);
  font-weight: 900;
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 2px rgba(17, 17, 17, 0.16);
  pointer-events: none;
}

/* founder — inverted plate */
.roster__row--founder { background: var(--ink); color: var(--cream); --spine-text: var(--cream); }
.roster__row--founder .roster__link:hover,
.roster__row--founder .roster__link:active { background: #232323; }
.roster__row--founder .roster__tag { color: #b9b6ae; }
.roster__row--founder .roster__photo img { border-color: var(--cream); }
.roster__row--founder .roster__num { -webkit-text-stroke-color: rgba(241, 239, 233, 0.25); }

/* =================================================================
   CLOSING CTA — resolution plate: the piece falls into place
   ================================================================= */
.final {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  padding: clamp(1.4rem, 5.5vw, 1.8rem) var(--gutter) clamp(1.5rem, 6vw, 2rem);
}

.final__title {
  font-weight: 900;
  font-size: clamp(2.1rem, 10.4vw, 2.9rem);
  line-height: 1;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}
.final__line { display: block; }

.final__line--outline {
  color: var(--cream);
  -webkit-text-stroke: 2px var(--ink);
  paint-order: stroke fill;
}
.final__line--red { color: var(--red); }

/* shape shelf: square, triangle, and the slot the circle drops into */
.fit { display: flex; }

.fit__cell {
  width: 3.4rem;
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--white);
  border: var(--rule);
}
.fit__cell + .fit__cell { border-left: 0; }
.fit__cell--slot {
  background: var(--cream);
  overflow: hidden;          /* the circle appears from the top edge */
}

.fit__sq {
  width: 46%;
  aspect-ratio: 1;
  background: var(--red);
}
.fit__tri {
  width: 54%;
  aspect-ratio: 1.08;
  background: var(--blue);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
.fit__circle {
  width: 58%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--yellow);
  border: 2.5px solid var(--ink);
}

/* the drop — plays once when the shelf scrolls into view */
@media (prefers-reduced-motion: no-preference) {
  .fit.sr-in .fit__circle {
    animation: drop-in 0.55s 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) both;
  }
  @keyframes drop-in {
    from { transform: translateY(-160%); }
    to   { transform: none; }
  }
}

/* the one testimonial — same plate language as the About card */
.quote {
  background: var(--white);
  color: var(--ink);
  border: var(--rule);
  border-left: 6px solid var(--red);
  padding: 0.95rem 1rem 1rem;
  box-shadow: 0.4rem 0.4rem 0 rgba(17, 17, 17, 0.12);
}

.quote__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin-bottom: 0.45rem;
}

.quote__stars {
  color: var(--yellow);
  font-size: 0.85rem;
  letter-spacing: 0.18em;
  text-shadow: 0 0 1px rgba(17, 17, 17, 0.65);
}

.quote__src {
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #4a4a48;
}

.quote__text {
  margin: 0;
  font-size: 0.98rem;
  font-weight: 700;
  line-height: 1.45;
}

.quote__by {
  margin-top: 0.4rem;
  font-size: 0.7rem;
  font-weight: 600;
  color: #4a4a48;
}

.final__meta {
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: center;
  color: #4a4a48;
}

/* =================================================================
   CONTACT — abstract Bauhaus map plate + split action tiles
   ================================================================= */

/* the map: ink streets, stripe texture, target pin — links to Maps */
.map {
  position: relative;
  display: block;
  margin-inline: var(--gutter);
  margin-bottom: clamp(1rem, 4.5vw, 1.4rem);
  border: var(--rule);
  background: var(--white);
  aspect-ratio: 16 / 11;
  overflow: hidden;
}

/* streets */
.map__st { position: absolute; background: var(--ink); }
.map__st--h  { left: 0; right: 0; top: 60%; height: 3px; }
.map__st--h2 { left: 0; right: 0; top: 22%; height: 2px; opacity: 0.22; }
.map__st--v  { top: 0; bottom: 0; left: 34%; width: 3px; }
.map__st--v2 { top: 0; bottom: 0; left: 74%; width: 2px; opacity: 0.22; }

/* city texture + landmarks */
.map__stripes {
  position: absolute;
  top: 0;
  right: 0;
  width: 24%;
  height: 16%;
  background: repeating-linear-gradient(90deg, var(--ink) 0 2px, transparent 2px 8px);
  opacity: 0.5;
}
.map__block { position: absolute; }
.map__block--blue {
  left: 80%;
  top: 38%;
  width: 0.65rem;
  aspect-ratio: 1;
  background: var(--blue);
}
.map__block--yellow {
  left: 13%;
  top: 78%;
  width: 0.7rem;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--yellow);
}

/* the shop: Bauhaus target pin at the crossing */
.map__pin {
  position: absolute;
  left: 34%;
  top: 60%;
  transform: translate(-50%, -50%);
  width: 1.9rem;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--red);
  border: 2.5px solid var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
}
.map__pin i {
  width: 0.6rem;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--white);
  border: 2px solid var(--ink);
}
@media (prefers-reduced-motion: no-preference) {
  .map__pin::after {
    content: "";
    position: absolute;
    inset: -5px;
    border-radius: 50%;
    border: 2.5px solid var(--red);
    animation: ping 2.4s ease-out infinite;
  }
  @keyframes ping {
    0%   { transform: scale(0.75); opacity: 0.9; }
    70%  { transform: scale(1.65); opacity: 0; }
    100% { transform: scale(1.65); opacity: 0; }
  }
}

/* address chip, attached to the pin */
.map__addr {
  position: absolute;
  left: calc(34% + 1.4rem);
  top: 60%;
  transform: translateY(-50%);
  z-index: 2;
  padding: 0.28rem 0.5rem;
  background: var(--white);
  border: 2px solid var(--ink);
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* hours — the sign on the door */
.map__hours {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  padding: 0.32rem 0.55rem;
  background: var(--white);
  border-right: 2px solid var(--ink);
  border-bottom: 2px solid var(--ink);
  font-size: 0.56rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.map__area {
  position: absolute;
  bottom: 0.55rem;
  left: 0.65rem;
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #8a887f;
}

/* explicit affordance, ink corner cell */
.map__open {
  position: absolute;
  bottom: 0;
  right: 0;
  z-index: 2;
  padding: 0.45rem 0.7rem;
  background: var(--ink);
  color: var(--cream);
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transition: background-color 0.15s;
}
.map__open b { color: var(--yellow); }
.map:hover .map__open, .map:active .map__open { background: var(--blue); }

/* live status band — circle means open, square means closed */
.status {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.75rem var(--gutter);
  border-top: var(--rule);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.status__dot {
  flex: none;
  width: 0.62rem;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--yellow);
  border: 2px solid var(--ink);
}
.status--closed .status__dot {
  border-radius: 0;
  background: var(--red);
}

.status__state { font-weight: 800; }

.status__hours {
  margin-left: auto;
  font-weight: 600;
  color: #4a4a48;
}

/* two channels — glyph cells + big values */
.chans { border-bottom: var(--rule); }

.chan {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 1rem;
  padding: 0.95rem var(--gutter);
  border-top: var(--rule);
  transition: background-color 0.15s;
}
.chan:hover, .chan:active { background: var(--white); }

.chan__cell {
  width: 3.1rem;
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: var(--rule);
}
.chan__cell--blue { background: var(--blue); }
.chan__cell--red  { background: var(--red); }

.chan__cell svg {
  width: 1.4rem;
  height: 1.4rem;
  fill: none;
  stroke: var(--cream);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.chan__ig-dot { fill: var(--cream); stroke: none; }

.chan__body {
  display: flex;
  flex-direction: column;
  gap: 0.12rem;
  min-width: 0;
}

.chan__label {
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #4a4a48;
}

.chan__value {
  font-size: clamp(1rem, 4.9vw, 1.15rem);
  font-weight: 900;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

.chan__micro {
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #4a4a48;
}

.chan__ne {
  font-size: 1.05rem;
  font-weight: 800;
  color: var(--red);
}

/* =================================================================
   FOOTER — closing plate: cream wordmark on ink
   ================================================================= */
.footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
  background: var(--ink);
  color: var(--cream);
  /* extra bottom space so the sticky book bar never covers the credit */
  padding: clamp(1.8rem, 7vw, 2.4rem) var(--gutter)
           calc(1.4rem + 3.5rem + env(safe-area-inset-bottom, 0px));
  text-align: center;
}

.footer__mark { width: clamp(10rem, 48vw, 12.5rem); height: auto; }

.footer__tag {
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(241, 239, 233, 0.7);
}

.footer__trio {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-block: 0.2rem;
}

.footer__copy {
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: rgba(241, 239, 233, 0.55);
}

.footer__credit {
  margin-top: 0.4rem;
  font-size: 0.58rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(241, 239, 233, 0.4);
  transition: color 0.15s;
}
.footer__credit b { font-weight: 800; }
.footer__credit:hover, .footer__credit:active { color: var(--yellow); }

/* =================================================================
   STICKY BOOK BAR — slides up when the hero CTA leaves the viewport
   ================================================================= */
.bookbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  margin-inline: auto;
  max-width: 30rem;
}
.bookbar[aria-hidden="true"] {
  transform: translateY(100%);
  visibility: hidden;
}

.bookbar__link {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.7rem;
  min-height: 3.5rem;
  padding: 0.6rem var(--gutter) calc(0.6rem + env(safe-area-inset-bottom, 0px));
  background: var(--ink);
  color: var(--white);
  font-size: 1rem;
  font-weight: 900;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.bookbar__link:focus-visible {
  outline-color: var(--yellow);
  outline-offset: -4px;
}

.bookbar__arrow {
  width: 1.4rem;
  height: 1.4rem;
  stroke: var(--red);
  stroke-width: 2.4;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (prefers-reduced-motion: no-preference) {
  .bookbar { transition: transform 0.25s ease, visibility 0s linear; }
  .bookbar[aria-hidden="true"] { transition: transform 0.25s ease, visibility 0s linear 0.25s; }
}

/* =================================================================
   LIGHTBOX — fullscreen viewer, poster chrome
   ================================================================= */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  background: rgba(17, 17, 17, 0.95);
  color: var(--cream);
}
.lightbox[hidden] { display: none; }

.lightbox__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.8rem var(--gutter);
}

.lightbox__count {
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.24em;
}

.lightbox__close,
.lightbox__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border: 2px solid var(--cream);
  color: var(--cream);
  transition: background-color 0.15s, color 0.15s;
}
.lightbox__close:hover, .lightbox__close:active,
.lightbox__btn:hover, .lightbox__btn:active {
  background: var(--cream);
  color: var(--ink);
}

.lightbox__close svg,
.lightbox__btn svg {
  width: 1.3rem;
  height: 1.3rem;
  stroke: currentColor;
  stroke-width: 2.2;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;   /* taps always target the button, not the icon */
}

.lightbox__stage {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.65rem;
  padding: 0 var(--gutter);
}

.lightbox__img {
  max-width: 100%;
  min-height: 0;
  object-fit: contain;
  border: 2.5px solid var(--cream);
  background: var(--ink);
}

/* plate caption under the exhibit */
.lightbox__cap {
  flex: none;
  max-width: 30ch;
  text-align: center;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1.45;
  color: rgba(241, 239, 233, 0.85);
}

.lightbox__nav {
  display: flex;
  justify-content: space-between;
  padding: 0.8rem var(--gutter) calc(0.8rem + env(safe-area-inset-bottom, 0px));
}

/* focus rings must stay visible on the dark chrome */
.lightbox :focus-visible {
  outline: 3px solid var(--yellow);
  outline-offset: 3px;
}

/* =================================================================
   SCROLL REVEALS — added by JS only when motion is allowed
   ================================================================= */
.sr {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.55s ease, transform 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}
.sr-in {
  opacity: 1;
  transform: none;
}

/* ---------- entrance reveals ---------- */
@media (prefers-reduced-motion: no-preference) {
  .reveal {
    animation: rise 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
  }
  .reveal--d1 { animation-delay: 0.09s; }
  .reveal--d2 { animation-delay: 0.18s; }

  @keyframes rise {
    from { transform: translateY(110%); }
    to   { transform: translateY(0); }
  }

  /* poster shapes settle in once on load, staggered, then still.
     The portrait itself never animates — it is the LCP element. */
  .stage__circle, .stage__square, .stage__tri, .stage__dots {
    animation: settle 0.7s ease-out both;
  }
  .stage__square { animation-delay: 80ms; }
  .stage__tri    { animation-delay: 160ms; }
  .stage__dots   { animation-delay: 240ms; }

  /* brand strip closes the shape stagger */
  .stage__brand  { animation: settle 0.7s ease-out 320ms both; }

  @keyframes settle {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
  }

  /* the rest of the hero joins the same print run — plate immediately,
     rating / CTA / utility landing just after their headline; one settle
     voice so the poster composes as a single sequence. Scoped to the
     hero: section plates keep their JS scroll reveal (.sr). */
  .hero .hero__plate { animation: settle 0.5s ease-out both; }
  .hero__rating      { animation: settle 0.55s ease-out 0.28s both; }
  .hero__actions     { animation: settle 0.55s ease-out 0.36s both; }
  .hero__util        { animation: settle 0.55s ease-out 0.44s both; }

  /* the vertical rail draws top → bottom, a ruling-pen stroke */
  .hero__rail {
    transform-origin: top;
    animation: rule-draw 0.7s 0.1s cubic-bezier(0.22, 1, 0.36, 1) both;
  }
  @keyframes rule-draw {
    from { transform: scaleY(0); }
  }

  /* the full-stop square lands last — punctuation after the type,
     same bounce as the closing plate's drop-in circle */
  .hero__title .t-dot {
    animation: dot-pop 0.35s 0.62s cubic-bezier(0.34, 1.56, 0.64, 1) both;
  }
  @keyframes dot-pop {
    from { transform: scale(0); opacity: 0; }
  }
}

