/* ===========================================================================
   Ashgrove Couture - concept site
   ---------------------------------------------------------------------------
   PALETTE, AND WHY IT IS THIS ONE.

   Every colour below was measured off the boutique's own material, not
   chosen from taste. The numbers are recorded so nobody has to re-guess:

     --gold  #E1BE53  the mean of 185,214 saturated bright pixels in the
                      shop's own Logo.jpg. Their monogram is gold on black,
                      so black-and-gold is the house's own ground, not a
                      "luxury" default. 10.74:1 on the ink below.
     --plum  #7A2E68 / #C98FBE
                      deepened and lightened from #4D314C, the mean of
                      12,861 pixels of the purple bandhani in their own
                      photographs 2 and 8. 7.41:1 on paper, 7.49:1 on ink.

   The ground is deliberately COOL near-black and COOL near-white. It is not
   cream and the accent is not brass: the first build of this page was cream
   plus brass plus espresso, which is hex-for-hex the palette the
   design-taste-frontend skill bans as the machine-made default for premium
   work, and it was rated 4 out of 10. The gold survives only because it is
   the shop's actual registered mark, and it is used as metal on the dark
   ground, never as a text colour on paper.

   SHAPE RULE, applied everywhere: every surface, image and field is square
   (radius 0). Only buttons and the monogram chip are pill. That is the
   shop's own store card, which is a square cream card with a pill button.
   =========================================================================== */

/* --------------------------------------------------------------------------
   Fonts. Self-hosted, so the page contacts no font company's server.
   Bodoni Moda is a Didone, which is the letterform fashion magazines have
   set for two centuries. Jost carries everything else.
   -------------------------------------------------------------------------- */
@font-face{
  font-family:"Bodoni Moda";
  src:url("fonts/bodoni-moda-latin.woff2") format("woff2");
  font-weight:400 900; font-style:normal; font-display:swap;
}
@font-face{
  font-family:"Bodoni Moda";
  src:url("fonts/bodoni-moda-latin-italic.woff2") format("woff2");
  font-weight:400 900; font-style:italic; font-display:swap;
}
@font-face{
  font-family:"Jost";
  src:url("fonts/jost-latin.woff2") format("woff2");
  font-weight:100 900; font-style:normal; font-display:swap;
}

/* --------------------------------------------------------------------------
   Tokens
   -------------------------------------------------------------------------- */
:root{
  --gold:#E1BE53;

  /* light is the default; dark is applied below by preference */
  --bg:#0D0E12;
  --surface:#15171D;
  --rule:#272B34;
  --text:#ECEDEF;
  --muted:#A2A6B0;
  --accent:#C98FBE;
  --accent-solid:#7A2E68;   /* their shopfront pillars, full strength */
  --accent-lift:#8E3A7A;
  --on-accent:#0D0E12;
  --shadow:22px 34px 60px -30px rgba(0,0,0,.75);

  /* Glass, tinted DARK rather than white.
     A white-tinted panel over a moving photograph makes the text contrast
     depend on whatever happens to be behind it that second - the risk the
     ui-ux-pro-max glassmorphism entry flags as requires:contrast-text-4.5.
     Measured over the brightest gold in this photograph a white tint fell to
     about 4.6:1 and would have gone under as the lights moved. A dark tint
     puts a floor under it: the blur, the bright edge and the inner highlight
     still read as glass, but the type stays legible whatever passes behind. */
  --glass:        rgba(13, 14, 18, 0.70);
  --glass-strong: rgba(13, 14, 18, 0.80);
  --glass-edge:   rgba(255, 255, 255, 0.20);
  --glass-blur:   20px;

  /* The three grounds the page alternates through, all taken from their own
     things: the ink of the signboard, the aubergine of the shopfront pillars,
     and the navy of the kurta in the photograph. */
  --ink:    #0D0E12;
  --ink-2:  #131520;
  --plum:   #1A0A17;
  --plum-2: #2A0F24;
  --navy:   #0A1020;
  --navy-2: #0E1730;

  /* Text ON the glass may not use --muted. Measured worst case - the panel
     sitting over a full-brightness gold specular - --muted #A2A6B0 comes out
     at 3.00:1 and fails. This value is 5.73:1 in that same worst case, and it
     is the whole reason the glass is legible whatever the lights are doing
     behind it. Do not "tidy" the panel back to --muted. */
  --on-glass:     #E2E4E8;
  --grain-op:.048;
  --chip:transparent;          /* the dark badge the monogram sits on */

  --display:"Bodoni Moda",Georgia,"Times New Roman",serif;
  --ui:"Jost",system-ui,-apple-system,"Segoe UI",sans-serif;

  /* one easing family, per emil-design-eng. never ease-in on UI. */
  --out:cubic-bezier(.23,1,.32,1);
  --io:cubic-bezier(.77,0,.175,1);

  --pad:clamp(1.25rem,5vw,5.5rem);
  --gap:clamp(2.5rem,7vw,7rem);
  --bar:34px;              /* height of the fixed concept bar */
  color-scheme: dark;
}



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

html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
  scroll-padding-top:calc(var(--bar) + 74px);
}
@media (prefers-reduced-motion:reduce){ html{scroll-behavior:auto} }

body{
  margin:0;
  background:var(--bg);
  color:var(--text);
  font-family:var(--ui);
  font-size:clamp(1rem,.96rem + .2vw,1.09rem);
  font-weight:300;
  line-height:1.62;
  letter-spacing:.005em;
  overflow-x:clip;              /* clip, not hidden: does not create a scroll box */
}

/* The grain. A data: URI, so it is bytes already inside this stylesheet and
   reaches out to nowhere. img-src in _headers allows data: for exactly this;
   without that allowance it was silently blocked on the live site once while
   looking correct locally. Fixed and pointer-events:none, so it never
   intercepts a click and never repaints on scroll. */
body::after{
  content:"";
  position:fixed; inset:0; z-index:60; pointer-events:none;
  opacity:var(--grain-op);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

img{max-width:100%; height:auto; display:block}

::selection{background:var(--accent); color:var(--on-accent)}

:where(a,button,input,textarea,[tabindex]):focus-visible{
  outline:2px solid var(--accent);
  outline-offset:3px;
}

.vh{
  position:absolute!important; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;
}

.skip{
  position:absolute; left:8px; top:-60px; z-index:120;
  background:var(--accent); color:var(--on-accent);
  padding:.7rem 1.1rem; font-family:var(--ui); font-weight:500;
  text-decoration:none; border-radius:999px;
  transition:top .18s var(--out);
}
.skip:focus{top:calc(var(--bar) + 8px)}

/* ==========================================================================
   GUARDRAIL 2a - the concept bar. Fixed, so it is on screen at every scroll
   position and at every width. Nothing is allowed to cover it: it holds the
   highest z-index on the page apart from the grain, which cannot be clicked.
   ========================================================================== */
.conceptbar{
  position:fixed; inset:0 0 auto 0; z-index:100;
  min-height:var(--bar);
  display:flex; align-items:center; justify-content:center;
  background:#7A2E68; color:#fff;
  padding:.32rem .9rem;
}
.conceptbar p{
  margin:0; text-align:center;
  font-family:var(--ui); font-weight:400;
  font-size:clamp(.66rem,.6rem + .34vw,.8rem);
  letter-spacing:.055em; text-transform:uppercase; line-height:1.35;
}
.conceptbar strong{font-weight:600}

/* --------------------------------------------------------------------------
   Header. One line at every desktop width, 68px tall.
   -------------------------------------------------------------------------- */
.topbar{
  position:sticky; top:var(--bar); z-index:90;
  display:flex; align-items:center; gap:1.25rem;
  height:68px; padding:0 var(--pad);
  background:color-mix(in srgb,var(--bg) 86%,transparent);
  backdrop-filter:blur(14px) saturate(1.4);
  -webkit-backdrop-filter:blur(14px) saturate(1.4);
  border-bottom:1px solid var(--rule);
}
@supports not (backdrop-filter:blur(2px)){ .topbar{background:var(--bg)} }

.brand{
  display:flex; align-items:center; gap:.6rem;
  min-height:44px;                       /* a real tap target, not just a logo */
  text-decoration:none; color:inherit; margin-right:auto; min-width:0;
}
.brand__chip{
  display:grid; place-items:center; flex:none;
  width:34px; height:34px; border-radius:999px; background:var(--chip);
}
.brand__chip img{width:20px; height:auto}
.brand__name{
  font-family:var(--display); font-weight:500;
  font-size:clamp(.92rem,.84rem + .4vw,1.16rem);
  letter-spacing:.085em; text-transform:uppercase;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}

.nav ul{display:flex; gap:clamp(.9rem,1.9vw,2rem); margin:0; padding:0; list-style:none}
.nav a{
  position:relative; display:block; padding:.55rem 0;
  color:var(--muted); text-decoration:none;
  font-size:.78rem; font-weight:400;
  letter-spacing:.13em; text-transform:uppercase; white-space:nowrap;
  transition:color .2s var(--out);
}
.nav a::after{
  content:""; position:absolute; left:0; right:0; bottom:.15rem; height:1px;
  background:var(--accent); transform:scaleX(0); transform-origin:left;
  transition:transform .28s var(--out);
}
@media (hover:hover) and (pointer:fine){
  .nav a:hover{color:var(--text)}
  .nav a:hover::after{transform:scaleX(1)}
}
.nav a:focus-visible{color:var(--text)}
@media (max-width:900px){ .nav{display:none} }

.cta{
  flex:none;
  display:inline-flex; align-items:center; justify-content:center;
  min-width:44px; min-height:44px; padding:.5rem 1.15rem;
  background:var(--accent); color:var(--on-accent);
  border-radius:999px; text-decoration:none;
  font-size:.74rem; font-weight:500; letter-spacing:.13em; text-transform:uppercase;
  white-space:nowrap;
  transition:transform .16s var(--out), filter .2s var(--out);
}
@media (hover:hover) and (pointer:fine){ .cta:hover{filter:brightness(1.1)} }
.cta:active{transform:scale(.97)}
.cta__short{display:none}

/* Narrow screens: shorten the button label rather than truncate the shop's
   own name. Verified at 390px, 360px and 320px. */
@media (max-width:600px){
  .cta__long{display:none}
  .cta__short{display:inline}
  .cta{padding:.6rem 1.05rem; letter-spacing:.1em}   /* min-height:44px still applies */
  .brand__name{font-size:.86rem; letter-spacing:.06em}
  .brand__chip{width:30px; height:30px}
  .brand__chip img{width:18px}
  .topbar{gap:.7rem}
}
@media (max-width:360px){
  .brand__name{font-size:.78rem; letter-spacing:.04em}
}

/* --------------------------------------------------------------------------
   Buttons. Pill, per the shape rule. Tap target never under 44px.
   -------------------------------------------------------------------------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center;
  min-height:48px; padding:.75rem 1.6rem;
  border:1px solid transparent; border-radius:999px;
  font-family:var(--ui); font-size:.79rem; font-weight:500;
  letter-spacing:.14em; text-transform:uppercase; white-space:nowrap;
  text-decoration:none; cursor:pointer;
  transition:transform .16s var(--out), background-color .2s var(--out),
             color .2s var(--out), filter .2s var(--out);
}
/* Deep, saturated, and square-shouldered. The pale --accent pill was almost
   invisible against a photograph and read as timid; this is 8.7:1 with white
   on it and behaves like a block of their own shopfront colour. */
.btn--solid{background:var(--accent-solid); color:#FFFFFF; border-radius:2px}
.btn--solid:hover{background:var(--accent-lift)}
.btn--line{background:transparent; color:var(--text); border-color:var(--glass-edge); border-radius:2px}
@media (hover:hover) and (pointer:fine){
  .btn--solid:hover{filter:brightness(1.1)}
  .btn--line:hover{border-color:var(--text)}
}
.btn:active{transform:scale(.97)}

.txt{
  display:inline-flex; align-items:center; gap:.45rem;
  min-height:44px;
  color:var(--accent); text-decoration:none;
  font-size:.8rem; font-weight:500; letter-spacing:.13em; text-transform:uppercase;
  border-bottom:1px solid var(--accent); align-self:flex-start;
  transition:opacity .2s var(--out);
}
@media (hover:hover) and (pointer:fine){ .txt:hover{opacity:.7} }

/* --------------------------------------------------------------------------
   Reveal on scroll.
   The hidden state applies ONLY when app.js has added .js to <html>. With no
   JavaScript, or if the script fails to parse, every section is simply
   visible. Nothing on this page waits for a script to be readable.
   -------------------------------------------------------------------------- */
.js .rv{opacity:0; transform:translateY(22px); will-change:opacity,transform}
.js .rv.in{
  opacity:1; transform:none;
  transition:opacity .75s var(--out), transform .75s var(--out);
}
@media (prefers-reduced-motion:reduce){
  .js .rv{opacity:1; transform:none; will-change:auto}
}

/* ==========================================================================
   1. HERO
   ========================================================================== */
/* The hero must fit the first screen: headline, subtext and BOTH buttons
   visible with no scroll. The type scale and the photograph are sized
   together from the viewport height, because sizing them independently is
   what pushed the buttons under the fold on the first pass. */




/* ---------------------------------------------------------------------------
   THE BANDS.
   Sections alternate between opaque grounds and a translucent one. The opaque
   bands give each section its own character and keep long passages of type
   easy to read; band-cloth opens a window in the middle of a section so the
   living surface underneath comes through, and closes again at the edges so
   the join is never a hard line. This rhythm is what stops a one-photograph
   page feeling empty between its high points.
   --------------------------------------------------------------------------- */
main, .topbar, .foot, .conceptbar{ position:relative; z-index:1; }
section{ position:relative; }

.band-ink{  background:linear-gradient(180deg, var(--ink)  0%, var(--ink-2)  100%); }
.band-plum{ background:linear-gradient(180deg, var(--plum) 0%, var(--plum-2) 100%); }
.band-navy{ background:linear-gradient(160deg, var(--navy) 0%, var(--navy-2) 100%); }

/* the window: opaque at both edges, 72% through the middle, so the cloth
   appears and disappears rather than switching on and off */
.band-cloth{
  background:linear-gradient(180deg,
    rgba(13,14,18,0.97)   0%,
    rgba(13,14,18,0.72)  22%,
    rgba(13,14,18,0.72)  78%,
    rgba(13,14,18,0.97) 100%);
}

/* a hairline of their gold between bands, the way a binding separates pages */
.band-ink   + .band-plum,  .band-plum  + .band-ink,
.band-cloth + .band-plum,  .band-plum  + .band-cloth,
.band-ink   + .band-cloth, .band-cloth + .band-ink{
  border-top:1px solid rgba(225,190,83,0.14);
}

/* Anything sitting inside a cloth window needs its own small floor, or the
   moving surface behind it competes with the words.

   NO backdrop-filter here, deliberately. Blurring the backdrop of twenty cards
   that all sit over a position:fixed surface is one of the most expensive
   things you can ask a phone to composite - it re-blurs the whole stack every
   scroll frame. A flat tint over the photograph reads almost identically and
   costs nothing. The blur is spent in exactly two places on this page, where
   it earns its keep: the hero panel and the top bar. */
.band-cloth .rail__item,
.band-cloth .q,
.band-cloth .find__card{
  background:var(--glass-strong);
  border:1px solid var(--glass-edge);
}

/* ---------------------------------------------------------------------------
   THE HERO, rebuilt 30 Aug 2026.
   It used to be two columns: words on the left, a boxed portrait photograph on
   the right. That is a Tier 1 editorial arrangement and it read as one. The
   cloth is now the whole ground, lit and moving, with a single pane of dark
   glass floating on it carrying the words - the same arrangement as the
   another build build, which is what this treatment is being matched to.
   --------------------------------------------------------------------------- */
.hero{
  position:relative;
  display:grid;
  place-items:center start;
  min-height:calc(100svh - var(--bar) - 68px);
  padding:clamp(2rem,6vw,5rem) var(--pad);
  max-width:1560px; margin-inline:auto;
  overflow:hidden;
  isolation:isolate;
}

/* THE GROUND, fixed behind the entire document.
   It used to sit inside the hero, which made the living cloth a hero
   decoration and left every section below it flat. Fixed, it is the floor the
   whole page walks over, and the bands decide how much of it shows. */
.cloth{
  position:fixed; inset:var(--bar) 0 0 0; margin:0; z-index:0;
  background:var(--ink);
  overflow:hidden;
  pointer-events:none;
}
.cloth__img,
.cloth__canvas{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover;
  display:block;
}
.cloth__img{
  /* dimmed a little so type has somewhere to sit even before WebGL starts,
     and so the still frame and the lit surface look like the same picture */
  filter:brightness(.82) saturate(1.04);
  transform:scale(1.02);
}
.cloth__canvas{ opacity:0; transition:opacity 900ms var(--ease-out,ease); }
html.cloth-on  .cloth__canvas{ opacity:1; }
html.cloth-on  .cloth__img{ opacity:0; transition:opacity 900ms var(--ease-out,ease); }
html.cloth-off .cloth__canvas{ display:none; }

/* the pane of glass */
.hero__panel{
  position:relative; z-index:1;
  width:min(100%, 40rem);
  margin-inline:0;
  padding:clamp(1.7rem,3.2vw,2.6rem) clamp(1.5rem,3vw,2.5rem);
  background:var(--glass);
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(150%);
  backdrop-filter:blur(var(--glass-blur)) saturate(150%);
  border:1px solid var(--glass-edge);
  border-radius:2px;
  box-shadow:
    0 1px 0 0 rgba(255,255,255,.10) inset,
    0 40px 90px -40px rgba(0,0,0,.85);
}
/* Where the browser cannot blur, the panel goes solid instead of transparent.
   A transparent panel with no blur is unreadable over a photograph. */
@supports not ((backdrop-filter:blur(2px)) or (-webkit-backdrop-filter:blur(2px))){
  .hero__panel{ background:var(--glass-strong); }
}

.hero__rule{
  display:block; width:clamp(3rem,7vw,5rem); height:2px; margin-bottom:1.5rem;
  background:linear-gradient(90deg,var(--gold),transparent);
}
.hero__panel .hero__sub{ color:var(--on-glass); }
.hero__where{
  margin:clamp(1.4rem,3vw,2rem) 0 0;
  padding-top:clamp(1.1rem,2.4vw,1.6rem);
  border-top:1px solid var(--rule);
  color:var(--on-glass);
  font-size:.95rem; line-height:1.6;
}
.hero__where strong{ color:var(--text); font-weight:600; }

@media (max-width:560px){
  .hero__panel{ padding:1.4rem 1.15rem; }
}

.hero__title{
  margin:0;
  font-family:var(--display);
  font-weight:500;
  font-size:clamp(2.3rem,.4rem + 4.7vw,4.9rem);
  line-height:1.05;                 /* clears the y descender in "your" */
  text-wrap:balance;                /* keeps the two lines evenly weighted */
  letter-spacing:-.018em;
  padding-bottom:.14em;             /* reserve under the italic descender */
}
.hero__title .word{display:block; overflow:hidden}
.hero__title em{
  font-style:italic; font-weight:400;
  color:var(--accent);
  padding-right:.06em;
}
/* the entrance. delays live here, not in a style attribute: an inline style
   attribute is blocked by style-src 'self' and was silently dropped on the
   live site once. */
.js .hero__title .word > *{display:block}
.js .hero__title .word{opacity:1}
.js .hero__title .word span,
.js .hero__title .word em{
  display:block;
  transform:translateY(105%);
  animation:rise .95s var(--out) forwards;
}
.js .hero__title .word:nth-child(1) :is(span,em){animation-delay:.06s}
.js .hero__title .word:nth-child(2) :is(span,em){animation-delay:.17s}
@keyframes rise{to{transform:translateY(0)}}
@media (prefers-reduced-motion:reduce){
  .js .hero__title .word :is(span,em){transform:none; animation:none}
}

.hero__sub{
  margin:clamp(1.4rem,2.5vw,2rem) 0 0;
  max-width:34ch;
  color:var(--muted);
  font-size:clamp(1rem,.95rem + .3vw,1.16rem);
}
.hero__acts{display:flex; flex-wrap:wrap; gap:.8rem; margin-top:clamp(1.6rem,3vw,2.4rem)}

/* The cloth panel. The canvas, when there is one, is laid exactly over the
   image and both are the same size, so switching between them cannot shift
   the layout by a pixel. */
/* Sized from HEIGHT, not width, so the panel can never grow taller than the
   screen and shove the buttons out of the first view. The width follows from
   the photograph's own 700x1035 proportion. */

.cloth__img,



/* the still stays underneath the canvas for the whole session, so a lost
   WebGL context (a laptop waking, a GPU reset) reveals the photograph
   rather than a blank rectangle. */

@media (max-width:900px){
  .hero{
    grid-template-columns:1fr;
    gap:1.75rem;
    min-height:0;
    padding-top:1.5rem;
  }
  .cloth{
    height:min(52vh,420px);
    justify-self:stretch; width:100%; aspect-ratio:auto;
    order:-1;
  }
  .hero__sub{max-width:46ch}
}

/* ==========================================================================
   2. STATEMENT
   ========================================================================== */
.creed{
  padding:clamp(4rem,10vw,9rem) var(--pad);
  border-top:1px solid var(--rule);
  text-align:center;
}
.creed__type{
  margin:0 auto; max-width:20ch;
  font-family:var(--display); font-weight:400;
  font-size:clamp(1.9rem,.85rem + 4.4vw,4.1rem);
  line-height:1.16; letter-spacing:-.012em;
}
.creed__type .line{display:block}
.creed__pop{color:var(--accent); font-style:italic}
.creed__note{
  margin:clamp(1.8rem,3vw,2.6rem) auto 0; max-width:44ch;
  color:var(--muted); font-size:.98rem;
}

/* ==========================================================================
   3. THE RAIL. Horizontal, snapped, pushable.
   ========================================================================== */
.rail{padding:clamp(3.5rem,8vw,7rem) 0; border-top:1px solid var(--rule)}
.rail__head{
  display:flex; flex-wrap:wrap; align-items:baseline; gap:.4rem 1.6rem;
  padding:0 var(--pad); margin-bottom:clamp(1.8rem,4vw,3rem);
}
.rail__head h2{
  margin:0; font-family:var(--display); font-weight:400;
  font-size:clamp(1.75rem,1rem + 2.9vw,3.1rem); letter-spacing:-.01em;
}
.rail__blurb{margin:0; color:var(--muted); font-size:.94rem}

.rail__track{
  display:flex; gap:clamp(.8rem,2vw,1.5rem);
  margin:0; padding:.5rem var(--pad) 1.5rem; list-style:none;
  overflow-x:auto; overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;
  scrollbar-width:thin; scrollbar-color:var(--rule) transparent;
}
.rail__track::-webkit-scrollbar{height:5px}
.rail__track::-webkit-scrollbar-thumb{background:var(--rule)}
.rail__track.dragging{scroll-snap-type:none; cursor:grabbing}
.rail__track.dragging *{pointer-events:none}

.piece{flex:0 0 auto; scroll-snap-align:center}
.piece figure{margin:0; width:clamp(15rem,42vw,23rem)}
.piece img{
  width:100%; aspect-ratio:3/4; object-fit:cover;
  background:var(--surface);
  transition:transform .55s var(--out), filter .55s var(--out);
}
.piece figcaption{
  margin-top:.85rem; color:var(--muted);
  font-size:.78rem; letter-spacing:.09em; text-transform:uppercase;
}
@media (hover:hover) and (pointer:fine){
  .piece figure:hover img{transform:scale(1.035); filter:brightness(1.05)}
}
@media (prefers-reduced-motion:reduce){
  .piece img{transition:none}
  .piece figure:hover img{transform:none}
}

/* ==========================================================================
   4. THE CLOTH, close up. Two-up, image leading.
   ========================================================================== */
.detail{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  align-items:center; gap:clamp(2rem,6vw,5.5rem);
  padding:clamp(3.5rem,8vw,7rem) var(--pad);
  border-top:1px solid var(--rule);
}
.detail__fig{margin:0; box-shadow:var(--shadow)}
.detail__fig img{width:100%; aspect-ratio:Reviewed on Google; object-fit:cover; background:var(--surface)}
.detail__copy h2{
  margin:0 0 1.2rem;
  font-family:var(--display); font-weight:400;
  font-size:clamp(1.7rem,1rem + 2.6vw,2.9rem);
  line-height:1.18; letter-spacing:-.01em; max-width:16ch;
}
.detail__copy p{margin:0 0 1.1rem; color:var(--muted); max-width:46ch}
.detail__copy p:last-child{color:var(--text)}
@media (max-width:820px){ .detail{grid-template-columns:1fr} }

/* ==========================================================================
   5. VISITING. Hairlines, not cards.
   ========================================================================== */
.visit{padding:clamp(3.5rem,8vw,7rem) var(--pad); border-top:1px solid var(--rule)}
.visit__title{
  margin:0 0 clamp(2rem,4vw,3rem);
  font-family:var(--display); font-weight:400;
  font-size:clamp(1.75rem,1rem + 2.9vw,3.1rem); letter-spacing:-.01em;
}
.ways{display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,17rem),1fr)); gap:0}
.way{
  display:flex; flex-direction:column; align-items:flex-start;
  gap:.85rem; padding:clamp(1.6rem,3vw,2.4rem) 0;
  border-top:1px solid var(--rule);
}
.way + .way{border-left:none}
@media (min-width:52rem){
  .ways{column-gap:clamp(2rem,5vw,4.5rem)}
  .way + .way{padding-left:clamp(2rem,5vw,4.5rem); border-left:1px solid var(--rule)}
}
.way h3{
  margin:0; font-family:var(--display); font-weight:500;
  font-size:clamp(1.15rem,1rem + .7vw,1.5rem); letter-spacing:.005em;
}
.way p{margin:0; color:var(--muted); max-width:38ch}

/* ==========================================================================
   6. FIND US
   ========================================================================== */
.find{padding:clamp(3.5rem,8vw,7rem) var(--pad) clamp(3rem,6vw,5rem); border-top:1px solid var(--rule)}
.find__title{
  margin:0; font-family:var(--display); font-weight:400;
  font-size:clamp(1.75rem,1rem + 2.9vw,3.1rem); letter-spacing:-.012em;
}
.find__sub{margin:.5rem 0 clamp(2rem,4vw,3rem); color:var(--muted)}

.map{
  position:relative; width:100%; aspect-ratio:16/7; min-height:250px;
  background:var(--surface); border:1px solid var(--rule); overflow:hidden;
}
.map iframe{position:absolute; inset:0; width:100%; height:100%; border:0}

.find__grid{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,20rem),1fr));
  gap:clamp(2.2rem,5vw,4.5rem); margin-top:clamp(2.2rem,5vw,3.5rem);
}

.facts{margin:0; display:grid; gap:0; align-content:start}
.fact{
  display:grid; grid-template-columns:minmax(6.5rem,auto) 1fr; gap:1rem;
  padding:.95rem 0; border-bottom:1px solid var(--rule);
}
.fact dt{
  color:var(--muted); font-size:.74rem;
  letter-spacing:.14em; text-transform:uppercase; padding-top:.2em;
}
.fact dd{margin:0; font-size:1rem}
.fact a{color:var(--accent); text-decoration:none; border-bottom:1px solid var(--accent)}
@media (hover:hover) and (pointer:fine){ .fact a:hover{opacity:.75} }

/* GUARDRAIL 3 - the dead form. The notice sits ABOVE the fields, in the
   accent colour, and is not distinguishable by colour alone: it is bordered,
   on its own surface, and opens with bold text saying it does not work. */
.enq h3{
  margin:0 0 1rem; font-family:var(--display); font-weight:400;
  font-size:clamp(1.3rem,1rem + 1.1vw,1.75rem);
}
.dead{
  margin:0 0 1.5rem; padding:1rem 1.15rem;
  background:var(--surface);
  border:1px solid var(--rule); border-left:3px solid var(--accent);
  color:var(--text); font-size:.9rem; line-height:1.6;
}
.dead strong{display:block; margin-bottom:.3rem; font-weight:600}
.dead a{color:var(--accent); font-weight:500}

.efm{display:grid; gap:1.1rem}
.field{display:grid; gap:.4rem; margin:0}
.field label{
  color:var(--muted); font-size:.74rem;
  letter-spacing:.14em; text-transform:uppercase;
}
.field input,.field textarea{
  width:100%; min-height:48px; padding:.7rem .85rem;
  font-family:var(--ui); font-size:1rem; font-weight:300;
  color:var(--text); background:var(--bg);
  border:1px solid var(--rule); border-radius:0;
  transition:border-color .2s var(--out);
}
.field textarea{min-height:104px; resize:vertical}
.field input:focus,.field textarea:focus{border-color:var(--accent)}
.efm .btn{justify-self:start}
.dead__said{
  margin:0; padding:.75rem .9rem;
  background:var(--surface); border:1px solid var(--rule);
  color:var(--text); font-size:.88rem;
}

/* --------------------------------------------------------------------------
   Footer, with GUARDRAIL 2b
   -------------------------------------------------------------------------- */
.foot{
  display:grid; justify-items:center; gap:.5rem;
  padding:clamp(3rem,6vw,5rem) var(--pad) clamp(2.5rem,5vw,4rem);
  border-top:1px solid var(--rule); text-align:center;
}
.foot__chip{
  display:grid; place-items:center;
  width:52px; height:52px; border-radius:999px; background:var(--chip);
  margin-bottom:.6rem;
}
.foot__chip img{width:30px; height:auto}
.foot__name{
  margin:0; font-family:var(--display); font-weight:500;
  font-size:1.05rem; letter-spacing:.11em; text-transform:uppercase;
}
.foot__line{margin:0; color:var(--muted); font-size:.9rem}
.foot__line a{
  color:var(--accent); text-decoration:none;
  border-bottom:1px solid var(--accent);   /* never colour alone */
  display:inline-block; min-height:auto;
}
.foot__note{
  margin:1.4rem 0 0; padding-top:1.2rem;
  border-top:1px solid var(--rule);
  width:100%; max-width:34rem;
  color:var(--muted); font-size:.78rem;
  letter-spacing:.16em; text-transform:uppercase;
}

/* --------------------------------------------------------------------------
   Print. The concept notice must survive being printed.
   -------------------------------------------------------------------------- */
@media print{
  .conceptbar{position:static}
  .topbar{position:static}

}

/* ==========================================================================
   ADDED 30 AUG 2026 - the door section, sub-pages, questions, cookie notice.
   Same tokens, same shape rule (everything square except pills), same
   easing. Nothing new is introduced that the rest of the page does not
   already use.
   ========================================================================== */

/* --------------------------------------------------------------------------
   5. THE DOOR. Copy left, shopfront right. A different layout family from
   .detail, which is image-left, so the page does not repeat itself.
   -------------------------------------------------------------------------- */
.door{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,.82fr);
  align-items:center; gap:clamp(2rem,6vw,5rem);
  padding:clamp(3.5rem,8vw,7rem) var(--pad);
  border-top:1px solid var(--rule);
}
.door__copy h2{
  margin:0 0 1.2rem;
  font-family:var(--display); font-weight:400;
  font-size:clamp(1.7rem,1rem + 2.6vw,2.9rem);
  line-height:1.18; letter-spacing:-.01em; max-width:15ch;
}
.door__copy p{margin:0 0 1.1rem; color:var(--muted); max-width:46ch}
.door__fig{margin:0; box-shadow:var(--shadow)}
.door__fig img{width:100%; height:auto; background:var(--surface)}
@media (max-width:820px){ .door{grid-template-columns:1fr} }

/* --------------------------------------------------------------------------
   7. QUESTIONS. Native <details>, so it opens with no JavaScript at all
   and is keyboard operable for free.
   -------------------------------------------------------------------------- */
.qs{padding:clamp(3.5rem,8vw,6rem) var(--pad); border-top:1px solid var(--rule)}
.qs__title{
  margin:0 0 clamp(1.6rem,3vw,2.4rem);
  font-family:var(--display); font-weight:400;
  font-size:clamp(1.75rem,1rem + 2.9vw,3.1rem); letter-spacing:-.01em;
}
.qs__list{max-width:60rem}
.qs .q{border-top:1px solid var(--rule)}
.qs .q:last-of-type{border-bottom:1px solid var(--rule)}
.q > summary{
  display:flex; align-items:center; gap:1rem;
  min-height:56px; padding:1rem 0;
  cursor:pointer; list-style:none;
  font-family:var(--display); font-weight:500;
  font-size:clamp(1.02rem,.95rem + .45vw,1.28rem);
  transition:color .2s var(--out);
}
.q > summary::-webkit-details-marker{display:none}
.q > summary::after{
  content:""; flex:none; margin-left:auto;
  width:11px; height:11px; border-right:1.5px solid var(--accent);
  border-bottom:1.5px solid var(--accent); transform:rotate(45deg) translateY(-3px);
  transition:transform .28s var(--out);
}
.q[open] > summary::after{transform:rotate(225deg) translateY(-3px)}
@media (hover:hover) and (pointer:fine){ .q > summary:hover{color:var(--accent)} }
.q > summary:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
.q__a{padding:0 0 1.4rem}
.q__a p{margin:0 0 .8rem; color:var(--muted); max-width:62ch}
.q__a p:last-child{margin-bottom:0}
.q__a a{color:var(--accent); text-decoration:none; border-bottom:1px solid var(--accent)}
.qs > .txt{margin-top:1.8rem}

/* --------------------------------------------------------------------------
   SUB-PAGES: about, questions, privacy
   -------------------------------------------------------------------------- */
.page{padding:0 0 clamp(2rem,5vw,4rem)}
.page__head{
  padding:clamp(2.5rem,6vw,5rem) var(--pad) clamp(1.5rem,3vw,2.5rem);
  border-bottom:1px solid var(--rule);
}
.page__title{
  margin:0;
  font-family:var(--display); font-weight:400;
  font-size:clamp(2.1rem,1rem + 4.2vw,4rem);
  line-height:1.08; letter-spacing:-.018em;
}
.page__lede{
  margin:1.1rem 0 0; max-width:52ch;
  color:var(--muted);
  font-size:clamp(1.02rem,.96rem + .3vw,1.18rem);
}
.page .qs__list--page{padding:0 var(--pad); margin-top:clamp(2rem,4vw,3rem)}

.prose{padding:clamp(2rem,5vw,3.5rem) var(--pad) 0; max-width:min(100%,64rem)}
.prose h2{
  margin:clamp(2rem,4vw,3rem) 0 .9rem;
  font-family:var(--display); font-weight:400;
  font-size:clamp(1.35rem,1rem + 1.3vw,1.95rem); letter-spacing:-.008em;
}
.prose h2:first-child{margin-top:0}
.prose p{margin:0 0 1.05rem; color:var(--muted); max-width:64ch}
.prose p strong{color:var(--text); font-weight:500}
.prose em{color:var(--text); font-style:italic}
.prose a{color:var(--accent); text-decoration:none; border-bottom:1px solid var(--accent)}
@media (hover:hover) and (pointer:fine){ .prose a:hover{opacity:.72} }
.prose code{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:.88em; color:var(--text);
  background:var(--surface); border:1px solid var(--rule); padding:.1em .38em;
}
.prose__updated{margin-top:2.5rem; font-size:.85rem}

/* a bordered aside, same device as the dead-form notice so the page has
   one visual language for "read this bit properly" */
.note{
  margin:clamp(1.8rem,3vw,2.4rem) 0;
  padding:1.2rem 1.35rem;
  background:var(--surface);
  border:1px solid var(--rule); border-left:3px solid var(--accent);
}
.note__h{margin:0 0 .7rem !important; font-size:1.05rem !important}
.note p{margin-bottom:.75rem}
.note p:last-child{margin-bottom:0}

.tbl{
  width:100%; border-collapse:collapse; margin:0 0 1.4rem;
  font-size:.92rem;
}
.tbl th,.tbl td{
  text-align:left; vertical-align:top;
  padding:.7rem .8rem .7rem 0; border-bottom:1px solid var(--rule);
  color:var(--muted);
}
.tbl th{
  color:var(--text); font-weight:500;
  font-size:.74rem; letter-spacing:.13em; text-transform:uppercase;
}
.tbl td:first-child{white-space:nowrap}

.consent-manage{
  margin:1.4rem 0 2rem; padding:1.2rem 1.35rem;
  background:var(--surface); border:1px solid var(--rule);
}
.consent-manage p{margin:0 0 .9rem; color:var(--text); max-width:62ch}

.cta-block{
  margin:clamp(2.5rem,6vw,4.5rem) var(--pad) 0;
  padding:clamp(2rem,5vw,3.2rem);
  background:var(--surface); border:1px solid var(--rule);
  text-align:center;
}
.cta-block h2{
  margin:0 0 .7rem;
  font-family:var(--display); font-weight:400;
  font-size:clamp(1.45rem,1rem + 1.7vw,2.3rem); letter-spacing:-.01em;
}
.cta-block p{margin:0 auto 1.5rem; max-width:44ch; color:var(--muted)}

/* --------------------------------------------------------------------------
   THE MAP, before consent
   -------------------------------------------------------------------------- */
/* .map__ask removed 30 Aug 2026: the map loads on its own now, so there is
   no "ask" panel to style. */

/* --------------------------------------------------------------------------
   FOOTER NAV
   -------------------------------------------------------------------------- */
.foot__nav{
  display:flex; flex-wrap:wrap; justify-content:center;
  gap:.4rem clamp(1rem,3vw,2rem); margin-top:1rem;
}
.foot__nav a{
  display:inline-flex; align-items:center; min-height:44px;
  color:var(--muted); text-decoration:none;
  font-size:.76rem; letter-spacing:.13em; text-transform:uppercase;
  border-bottom:1px solid transparent;
  transition:color .2s var(--out), border-color .2s var(--out);
}
@media (hover:hover) and (pointer:fine){
  .foot__nav a:hover{color:var(--text); border-bottom-color:var(--accent)}
}
.foot__nav a[aria-current="page"]{color:var(--text); border-bottom-color:var(--accent)}
.nav a[aria-current="page"]{color:var(--text)}
.nav a[aria-current="page"]::after{transform:scaleX(1)}

/* --------------------------------------------------------------------------
   THE COOKIE NOTICE. A notice, not a gate: this page sets nothing by
   itself, so there is nothing to refuse and no "reject" button to fake.
   It is built by app.js so its wording cannot drift across four pages.
   -------------------------------------------------------------------------- */
.cookiebar{
  position:fixed; z-index:95;
  left:clamp(.5rem,2vw,1.25rem); right:clamp(.5rem,2vw,1.25rem);
  bottom:clamp(.5rem,2vw,1.25rem);
  max-width:44rem; margin-inline:auto;
  display:flex; flex-wrap:wrap; align-items:center; gap:.9rem 1.2rem;
  padding:1rem 1.15rem;
  background:var(--surface);
  border:1px solid var(--rule); border-left:3px solid var(--accent);
  box-shadow:var(--shadow);
  transform:translateY(120%); opacity:0;
  transition:transform .42s var(--out), opacity .42s var(--out);
}
.cookiebar--in{transform:none; opacity:1}
.cookiebar--out{transform:translateY(120%); opacity:0}
.cookiebar__text{
  flex:1 1 20rem; margin:0;
  color:var(--muted); font-size:.86rem; line-height:1.55;
}
.cookiebar__text strong{color:var(--text); font-weight:500}
.cookiebar__text a{color:var(--accent); text-decoration:none; border-bottom:1px solid var(--accent)}
.cookiebar__btn{flex:none; min-height:44px; padding:.6rem 1.3rem; font-size:.74rem}
@media (prefers-reduced-motion:reduce){
  .cookiebar{transition:none; transform:none; opacity:1}
  .cookiebar--out{display:none}
}

/* Safety net found on 30 Aug 2026: a long button label cannot wrap because
   .btn is white-space:nowrap, so on a 390px screen it pushed the page 66px
   wide and created a horizontal scrollbar. The label was shortened, and
   below 420px a button is allowed to wrap rather than overflow. A wrapped
   button is ugly; a horizontally scrolling page is broken. */
@media (max-width:420px){
  .btn{white-space:normal; text-align:center; max-width:100%}
}

/* Anything that only works when a script is running is hidden until one is.
   A button that does nothing is worse than no button. */
.js-only{display:none}
.js .js-only{display:inline-flex}

/* ---------------------------------------------------------------------------
   SINGLE MODE, committed 30 Aug 2026.
   This site used to carry a full light palette AND a dark override, while its
   hero stayed dark in both. In light mode a reader scrolled from a dark,
   art-directed hero straight into a near-white page - two sites stapled
   together. His words: "in light mode it's completely garbage".
   The dark palette is now the only palette, the way another build has always been.
   Do not reintroduce a prefers-color-scheme block here.
   --------------------------------------------------------------------------- */

/* Concept-site additions. */
.map-stub{padding:28px 24px;border:1px solid currentColor;opacity:.75;font-size:.95em}
