/* ==========================================================================
   SARACEN THREADS — DESIGN AUTHORITY v2.0
   Chief Design Officer. Loads LAST. Nothing after it.

   THE POSITION
   This is not a shop. It is a dealer's room: a private gallery that handles
   the textiles of the Eastern courts. Objects hang on dark walls under pooled
   light, each one labelled, none of them crowded. Everything below serves
   that one sentence.

   THE GRAMMAR, AND WHY IT SPLITS IN TWO
   Indo-Saracenic and Mughal are not the same thing, and the gap between them
   is the system.

     MUGHAL is the OBJECT — the lobed medallion, the corner spandrels, the
     pendants, the wide band between two narrow ones. It already exists, on
     the loom, unchanged since the 1500s. We never redraw it and never
     recolour it.

     INDO-SARACENIC is the HOUSE — a nineteenth-century British style that
     took Mughal form and built English institutions with it. Which is the
     literal architecture of "an English house selling the textiles of the
     Eastern courts". It is the frame: cusped arch, jali screen, khatam star,
     aina-kari facet, hairline gold.

   The frame never competes with the content. The instant the ornament is as
   loud as the textile, we are selling wallpaper.

   FOUR RULES THAT ARE NOT NEGOTIABLE
   1  Dark ground. Always. No pale section, no cream band, no light mode.
   2  The object is the brightest thing on the screen. Everything else sits
      in the bottom third of the value range. That is how a spotlight works.
   3  Gold is a metal, so it has range — tarnish at the edge, glint at the
      centre. Flat yellow reads cheap and always will.
   4  One red. Madder, the dye in the goods. It is sealing wax, not paint.
      It appears at moments of consequence and nowhere else.
   ========================================================================== */

/* ==========================================================================
   1 · TOKENS
   ========================================================================== */
:root{

  /* ---- GROUNDS ------------------------------------------------------------
     Warm blacks. Bistre and bitumen, never neutral. A cold black reads as
     software; a warm black reads as an old building with the lamps on.
     --ground-1 is LOCKED: the ad creative must use this exact value or the
     tap-to-load transition reads as a different website and she leaves. */
  --ground-0:#0A0705;   /* the void. plate mounts, the deepest recess */
  --ground-1:#120C07;   /* THE PAGE. locked. */
  --ground-2:#1A1109;   /* raised surfaces, bands, the drawer */
  --ground-3:#241810;   /* lifted: pressed, active, selected */

  /* ---- GOLD — a metal, in five steps -------------------------------------- */
  --gold-0:#4A3618;     /* tarnish. edges, the far side of a bevel */
  --gold-1:#6E5326;     /* rules and borders at rest */
  --gold-2:#A98B4B;     /* base gold. the house colour. */
  --gold-3:#D8C596;     /* gold as text on dark */
  --gold-4:#F0DCA8;     /* the glint. highlights only, never a fill */

  /* ---- INK ----------------------------------------------------------------
     Reversed type blooms and thins on a phone, so every step is one lighter
     than it would be on paper, and nothing runs below 400 weight. */
  --ink-0:#FBF6EC;      /* the label. brightest type on the page. */
  --ink-1:#F4ECDC;      /* headings */
  --ink-2:#E2D5BC;      /* body */
  --ink-3:#A8977A;      /* meta, kickers, dimensions */
  --ink-4:#6E6250;      /* disabled, rule text */

  /* ---- THE ONE RED — madder / lac ----------------------------------------- */
  --lac-0:#3E1410;
  --lac-1:#6E2A22;
  --lac-2:#8F4235;

  /* ---- LINES --------------------------------------------------------------
     A dealer's frame is a hairline. Anything thicker is a picture frame from
     a high street shop. */
  --rule:rgba(169,139,75,.26);
  --rule-2:rgba(169,139,75,.44);
  --rule-faint:rgba(169,139,75,.12);
  --hair:1px;

  /* ---- TYPE --------------------------------------------------------------- */
  --display:"Cormorant Garamond",Garamond,"Times New Roman",serif;
  --body:"Jost","Helvetica Neue",Arial,sans-serif;

  --t-hero:clamp(2.6rem,11vw,5.6rem);
  --t-xl:clamp(2rem,8vw,3.4rem);
  --t-lg:clamp(1.5rem,5.6vw,2.2rem);
  --t-md:clamp(1.2rem,4.4vw,1.55rem);
  --t-body:1rem;
  --t-small:.86rem;
  --t-label:.62rem;      /* the wall label. tracked, never smaller than this. */

  --track-label:.28em;
  --track-mark:.22em;

  /* ---- SPACE — one scale, nowhere overridden ------------------------------ */
  --space-section:64px;
  --space-block:32px;
  --space-element:16px;
  --gutter:20px;
  --measure:64ch;

  /* ---- THE STACK — every fixed thing, in the order she meets them --------- */
  --z-head:40;
  --z-shopbar:50;
  --z-consent:60;
  --z-drawer:80;
  --z-veil:100;

  /* ---- MOTION — a dealer moves slowly ------------------------------------- */
  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-long:cubic-bezier(.19,1,.22,1);
}
@media (min-width:900px){
  :root{ --space-section:120px; --gutter:44px; }
}
@media (max-width:380px){
  :root{ --gutter:16px; --space-section:52px; }
}

/* ==========================================================================
   2 · THE PAGE
   ========================================================================== */
html{  overflow-x:hidden; -webkit-text-size-adjust:100% }
body{
  margin:0;
  
  
  font-family:var(--body);
  font-weight:400;
  font-size:var(--t-body);
  line-height:1.68;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
  max-width:100%;
  /* the lamps. two pools of warmth so the ground is lit, not printed. */
  
}
img,svg,video{ max-width:100%; display:block }
img{ height:auto }
a{  text-decoration:none }

/* ==========================================================================
   3 · TYPE
   ========================================================================== */
.d,h1,h2,h3{
  font-family:var(--display);
  font-weight:300;
  line-height:1.1;
  letter-spacing:-.005em;
  
  margin:0;
  text-wrap:balance;
}
.d--hero{ font-size:var(--t-hero); font-weight:400; font-style:italic; line-height:1.02 }
.d--xl{ font-size:var(--t-xl) }
.d--lg{ font-size:var(--t-lg) }
.d--md{ font-size:var(--t-md) }

/* the kicker is a wall label, so it is typeset as one */
.kicker,.label{
  font-family:var(--body);
  font-size:var(--t-label);
  font-weight:400;
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  
  margin:0 0 var(--space-element);
}
p,li,dd{ margin:0 0 1rem; font-size:var(--t-body); line-height:1.7; overflow-wrap:break-word }
.lede{ max-width:var(--measure); }
.prose{ max-width:var(--measure); margin-inline:auto; font-size:var(--t-body); line-height:1.8 }
.prose h1,.prose h2{ margin:2.4rem 0 1rem }
.muted,small,.small{  font-size:var(--t-small) }
em,i{ font-style:italic }
strong,b{ font-weight:500; }

/* a price is a fact, not a shout */
.price,.folio__price,.pdp__price{
  font-family:var(--display);
  font-weight:400;
  font-size:var(--t-md);
  
  letter-spacing:.01em;
  white-space:nowrap;
}

/* ==========================================================================
   4 · ORNAMENT — Indo-Saracenic, and only in the margin
   The hashia rule: a Mughal page carries its ornament in the margin and
   mounts the painting whole. We do the same. No ornament crosses a plate.
   ========================================================================== */

/* the khatam divider — the house mark as a section break */
.rule-khatam{
  display:flex; align-items:center; gap:16px;
  margin:0 0 var(--space-block);
  
}
.rule-khatam::before,.rule-khatam::after{
  content:""; height:var(--hair); flex:1;
  
}
.rule-khatam svg{ width:20px; height:20px; flex:none }

/* jali — perforated stone. a texture, at the threshold of visibility. */
.jali{ position:relative }
.jali::before{
  content:""; position:absolute; inset:0; pointer-events:none; opacity:.5;
   background-size:40px 40px;
}

/* the spot — an object should look lit, not placed */
.spot{ position:relative; isolation:isolate }
.spot::before{
  content:""; position:absolute; z-index:-1; inset:-14% -8% -20%;
  
  pointer-events:none;
}

/* ==========================================================================
   5 · THE HEADER — one model, sticky, in the flow
   saracen.css had position:fixed and layout.css had position:sticky, both
   live. The bar overlapped content on some pages and reserved phantom space
   on others. Sticky wins; the fixed model is fully unwound here.
   ========================================================================== */
.head{
  position:sticky !important;
  top:0; left:auto; right:auto; bottom:auto;
  width:100%;
  z-index:var(--z-head);
  padding-top:env(safe-area-inset-top,0px);
  
  border-bottom:var(--hair) solid var(--rule);
  /* no  
}
.head__bar{
  display:grid;
  grid-template-columns:48px minmax(0,1fr) 48px;
  align-items:center; gap:8px;
  padding:.9rem max(var(--gutter),env(safe-area-inset-left,0px));
}
.head.is-stuck .head__bar{ padding-block:.6rem }
.head__mark{ text-align:center; min-width:0 }
.head__marktext{
  font-family:var(--display); font-weight:400;
  font-size:clamp(.95rem,4vw,1.18rem);
  letter-spacing:var(--track-mark); text-transform:uppercase;
   white-space:nowrap; display:block;
}
.head__tag{
  display:block; margin-top:3px;
  font-family:var(--body); font-size:.48rem;
  letter-spacing:var(--track-label); text-transform:uppercase;
  
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
@media (max-width:400px){ .head__tag{ display:none } }

.head__burger,.head__cart{
  min-height:48px; min-width:48px;
  display:grid; place-items:center;
   border:0; padding:0; cursor:pointer;
  font-family:var(--body); font-size:.66rem;
  letter-spacing:.2em; text-transform:uppercase; 
}
.head__burger span{ display:block; width:22px; height:var(--hair);  margin:4px auto }
.head__n{
  display:inline-grid; place-items:center; min-width:18px; height:18px;
  margin-left:5px; padding:0 4px;
   
  font-size:.58rem; font-weight:500; border-radius:9px;
}
/* THE NAV — CEO order, 22 Sep.
   The fault was not the typeface. layout.css set `.head__nav{gap:8px}`, which
   loaded after the 2.6rem in saracen.css and won. The gap between items then
   sat at roughly the letter-spacing INSIDE them, so the word boundaries
   dissolved and four links read as one continuous phrase:

       THE FLOOR THE HOUSE DELIVERY CONTACT

   Keep the tracking — it is doing the right thing for the brand. Widen the
   gaps and add a separator.

   Spec: gap >= 3x the letter-spacing inside each item. At .72rem the tracking
   is .2em = 2.3px, so the floor is 7px; this runs at 2.6rem = 41.6px, which is
   18x. The rule is a floor, not a target, and generosity here is free. */
.head__nav{
  display:flex; justify-content:center; align-items:center;
  gap:2.6rem;                        /* >= 3x the .2em tracking, by a long way */
  padding:0 var(--gutter) .9rem;
}
.head__nav a{
  position:relative;
  
  font-size:.72rem; letter-spacing:.2em; text-transform:uppercase;
  min-height:44px; display:inline-flex; align-items:center;
  padding-inline:4px;                /* 8px clear between adjacent targets */
}
/* a low-contrast middot between items, never after the last */
.head__nav a + a::before{
  content:"\00B7";
  position:absolute; left:calc(-1.3rem - 2px);
   opacity:.55;
  letter-spacing:0; pointer-events:none;
}
.head__nav a:hover{ }
.head__nav a[aria-current="page"]{ }

/* Never a horizontal row on a phone. Below 620px the bar is hidden and the
   items live one-per-line behind the hamburger, which is what .drawer is. */
@media (max-width:619px){ .head__nav{ display:none !important } }

/* ==========================================================================
   6 · THE DRAWER
   Was z-index 55 under a z-index 60 header, so it opened underneath and the
   first item was permanently clipped. Transition delays only reached
   nth-child(4), so items 5 and 6 sat at opacity 0 forever.
   ========================================================================== */
.drawer{
  position:fixed; inset:0;
  z-index:var(--z-drawer) !important;
  
   
  display:flex; flex-direction:column; justify-content:flex-start; gap:0;
  padding:max(96px,calc(env(safe-area-inset-top,0px) + 96px)) 8vw
          max(32px,env(safe-area-inset-bottom,0px));
  overflow-y:auto; -webkit-overflow-scrolling:touch;
}
.drawer::after{                 /* aina in the margin, barely there */
  content:""; position:absolute; inset:0; pointer-events:none;
   background-size:120px 120px; opacity:.05;
}
.drawer a{
  position:relative; z-index:1;
  font-family:var(--display); font-weight:300;
  font-size:clamp(1.5rem,7vw,2.2rem);
  
  padding:.55rem 0; min-height:56px;
  border-bottom:var(--hair) solid var(--rule);
}
.drawer a small{
  display:block; margin-top:.2rem;
  font-family:var(--body); font-size:.55rem;
  letter-spacing:var(--track-label); text-transform:uppercase; 
}
.drawer.is-open a:nth-child(5){ transition-delay:.44s }
.drawer.is-open a:nth-child(6){ transition-delay:.51s }
.drawer.is-open a:nth-child(7){ transition-delay:.58s }
.drawer__close{
  position:absolute; z-index:2;
  top:max(14px,calc(env(safe-area-inset-top,0px) + 14px));
  right:var(--gutter);
  width:48px; height:48px; display:grid; place-items:center;
   border:0; padding:0; cursor:pointer;
   font-family:var(--body); font-size:1.5rem; line-height:1;
}
body.is-locked{ overflow:hidden }

/* ==========================================================================
   7 · THE RAIL — the bug that broke the shop
   .folios was defined SEVEN times across three stylesheets. Two set
   grid-template-columns (explicit tracks), three set grid-auto-columns
   (implicit). layout.css loads last and reimposed one explicit 1fr track on a
   container already switched to grid-auto-flow:column with overflow-x:auto.
   Item 1 took the explicit track, the rest went implicit, width went
   indefinite, track sizing collapsed to min-content — and min-content for a
   text node is the width of its widest single character. Hence product names
   rendering as vertical columns of letters, prices printing on top of each
   other, and taps landing on overlapping slivers instead of products.

   Flex, not grid. Flex cannot be half-overridden by a grid-template-columns
   declaration arriving from another file.
   ========================================================================== */
.folios{
  display:flex !important;
  flex-wrap:wrap;
  gap:var(--space-block);
  grid-template-columns:none !important;
  grid-auto-columns:auto !important;
  grid-auto-flow:row !important;
  overflow:visible; margin:0; padding:0;
}
.folio{
  display:block;
  flex:1 1 100%;
  min-width:0;                  /* the line that stops min-content collapse */
  max-width:100%;
}
@media (max-width:619px){
  .folios{
    flex-wrap:nowrap; overflow-x:auto;
    scroll-snap-type:x mandatory; -webkit-overflow-scrolling:touch;
    scrollbar-width:none;
    margin-inline:calc(var(--gutter) * -1);
    padding-inline:var(--gutter);
    padding-bottom:1.2rem;
  }
  .folios::-webkit-scrollbar{ display:none }
  .folio{ flex:0 0 78vw; max-width:320px; scroll-snap-align:center }
}
@media (min-width:620px){ .folio{ flex:0 1 calc(50% - var(--space-block)/2) } }
@media (min-width:900px){ .folio{ flex:0 1 calc(25% - var(--space-block)*3/4) } }

.swipe-hint{
  font-family:var(--body); font-size:.54rem;
  letter-spacing:var(--track-label); text-transform:uppercase;
   margin:0 0 .8rem;
}
@media (min-width:620px){ .swipe-hint{ display:none } }

/* the same disease, same cure, everywhere else it repeats */
.why,.vs,.sets,.rooms,.cards,.grid,.strip__in{ min-width:0 }
.why>*,.vs>*,.sets>*,.rooms>*,.cards>*{ min-width:0 }

/* ==========================================================================
   8 · THE PLATE AND THE WALL LABEL
   A card carries a badge, a price and an add-to-cart. A gallery carries a
   plate and a label. This converts one into the other.

   The mount is commercial, not decorative. Ten of the fifteen palettes are
   pale-ground — The Winter Palace #CFC6B6, The Rose Salon #DED3CD, every
   white-base counterpane. Against a near-black page those glare while The
   Indigo Medallion sits back, and a rail mixing them looks broken rather than
   curated. A fixed dark mount equalises optical weight, so a white cloth and
   a navy panel hang as equals.
   ========================================================================== */
.folio__mount{
  position:relative;
  
  border:var(--hair) solid var(--rule);
  padding:clamp(12px,3.2vw,20px);
  overflow:hidden;
  transition:border-color .5s var(--ease);
}
.folio__mount::after{           /* the hairline inner frame. the dealer's line. */
  content:""; position:absolute; inset:7px;
  border:var(--hair) solid var(--rule-faint);
  pointer-events:none;
}
.folio:hover .folio__mount,.folio:focus-visible .folio__mount{ }

.folio__art{
  position:relative;
     /* was #F4EEE0 / #FAF6EC — a cream
                                              lightbox on a black page, and it
                                              was defined twice */
  aspect-ratio:4/5;
  display:grid; place-items:center;
  overflow:hidden;
}
.folio__art img,.folio__art svg{ width:100%; height:100%; object-fit:cover }
.folio__art::after{             /* the pooled light */
  content:""; position:absolute; inset:0; pointer-events:none;
  
}

/* the label */
.folio__meta{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:1rem; flex-wrap:wrap;     /* price drops below the name rather than
                                   printing on top of it */
  margin-top:1rem; padding-bottom:.55rem;
  border-bottom:var(--hair) solid var(--rule);
}
.folio__name{
  font-family:var(--display); font-weight:300;
  font-size:clamp(1.15rem,4.4vw,1.42rem); line-height:1.18;
   margin:0;
  min-width:0; flex:1 1 auto; overflow-wrap:break-word;
}
.folio__price{ flex:0 0 auto }
.folio__note{
  margin:.75rem 0 0; font-size:var(--t-small); line-height:1.62;
   min-width:0; overflow-wrap:break-word;
}
/* the colourway dots are the only place a product's own colour is allowed to
   touch the page ground */
.folio__ways{ display:flex; gap:6px; margin-top:.9rem }
.folio__ways i{
  width:11px; height:11px; border-radius:50%;
  
}

/* ==========================================================================
   9 · BUTTONS — a dealer does not shout
   ========================================================================== */
.btn,.cta,button.btn,a.btn{
  display:inline-flex; align-items:center; justify-content:center;
  min-height:48px; padding:1rem 2.4rem;
  font-family:var(--body); font-size:.68rem; font-weight:400;
  letter-spacing:var(--track-label); text-transform:uppercase;
  
  
  border:var(--hair) solid var(--gold-2);
  cursor:pointer;
  transition:background .4s var(--ease),border-color .4s var(--ease),color .4s var(--ease);
}
.btn:hover,.cta:hover{   }
.btn--fill,.btn--buy,.cta--buy{
     font-weight:500;
}
.btn--fill:hover,.btn--buy:hover,.cta--buy:hover{   }
.btn--light{   }
.btn--light:hover{  }
.btn--quiet{  }
.cta--off{ opacity:.42; border-style:dashed; pointer-events:none; cursor:not-allowed }

/* ==========================================================================
   10 · PALE GROUNDS — struck
   Standing instruction: dark ground, cream and gold ornament, no exceptions.
   The House page dropped to a cream field halfway down, which is a different
   brand appearing mid-scroll.
   ========================================================================== */
.light,section.light,.band--light,.paper,.cream{
  
  
}
.light h1,.light h2,.light h3,.light .d{ }
.light .kicker,.light .muted,.light small{ }
.light a{ }

/* the one red, used correctly: a sealed band, not a page */
.blood,.band--blood,.strip--blood{
   
  border-block:var(--hair) solid rgba(169,139,75,.22);
}
.dark,.gallery{  }

/* ==========================================================================
   11 · RHYTHM
   White space is what makes £499 look correct. Density reads as a discount
   site. When unsure, double it.
   ========================================================================== */
section{ padding-block:var(--space-section) }
.wrap,.sec__in{
  padding-inline:max(var(--gutter),env(safe-area-inset-left,0px))
                 max(var(--gutter),env(safe-area-inset-right,0px));
}
.strip{ padding-block:var(--space-block); display:block }
.mt1{ margin-top:var(--space-element) } .mt2{ margin-top:var(--space-block) }
.mt3{ margin-top:var(--space-section) }
main>section:first-child{ padding-top:var(--space-block) }

/* ==========================================================================
   12 · THE COOKIE NOTICE
   Correction to v2.0. This section previously styled .consent__in / __t / __a,
   which is a full-width bottom bar that NO markup renders — tracking.php emits
   .consent__row / .consent__b, the small bottom-left notice. So v2.0 was
   styling dead code while overriding the live component's padding and border.
   The dead rule has now been deleted from shop.css and this block dresses the
   real one in the ramps instead of fighting its geometry.

   Two things here are deliberate and must not be "tidied":

   The two buttons are the same size, weight and colour. A dimmed Decline
   beside a bright Accept is the exact pattern the ICO writes to people about.
   Do not fill the Accept button.

   On a phone the notice SHIFTS UP above the buy bar rather than hiding. v2.0
   set display:none when the buy bar was up, which removes a legal notice to
   make room for a button. Wrong, and worse UX than moving it 84px.
   ========================================================================== */
.consent{
  
  border:var(--hair) solid var(--rule-2);
  
  font-size:.76rem; line-height:1.58;
  
}
.consent a{  text-decoration:underline; text-underline-offset:2px }
.consent__row{ gap:.5rem; margin-top:.75rem }
.consent__b{
  font-family:var(--body); font-size:.64rem; font-weight:400;
  letter-spacing:var(--track-label); text-transform:uppercase;
  
  
  border:var(--hair) solid var(--gold-1);
  min-height:44px; padding:.55rem .7rem;
  transition:background .3s var(--ease),border-color .3s var(--ease);
}
@media (hover:hover){
  .consent__b:hover{  }
}
@media (hover:none){ .consent__b:active{ } }

/* the drawer is the one thing that outranks it, because it covers the screen */
body.is-locked .consent,
.drawer.is-open ~ .consent{ opacity:0; pointer-events:none }

/* ==========================================================================
   12b · THE LAST THREE PALE GROUNDS
   Found on a sweep of the merged build. All three predate v2.0 and all three
   breach the standing instruction.

   .screen is the interesting one. It was a cream-to-sand gradient with the
   jali laid over it — a pale panel wearing a stone screen. That is backwards.
   A jali is lit FROM BEHIND. You read it as dark perforated stone against a
   glow, never as a pale field. The corrected version is darker AND more
   accurate, which is usually how these go.
   ========================================================================== */
.screen{
  
  position:relative; overflow:hidden;
}
.screen::before{              /* the light behind the stone */
  content:""; position:absolute; inset:-20%;
  
  pointer-events:none;
}
.screen__mesh{                /* the stone itself, not a decal */
  position:absolute; inset:0;
   background-size:40px 40px;
  opacity:1;
}
.screen__msg{ position:relative; z-index:2; }
.screen__msg .d,.screen__msg h2,.screen__msg h3{ }

/* the hero call to action. Was a cream pill with a 3px madder border — the
   brightest object on the page, competing with the piece it sits under, inside
   a frame three times heavier than every other line in the system. */
.ivan__cta{
  
  
  border:var(--hair) solid var(--gold-2) !important;
  padding:.85rem 1.8rem !important;
  min-height:48px; display:inline-flex; align-items:center;
  letter-spacing:var(--track-label);
   
  transition:background .4s var(--ease),border-color .4s var(--ease);
}
.ivan__cta:hover{  }

/* the buy button is gold, not cream. Cream is what the goods are made of; gold
   is what the house is made of, and the button belongs to the house. */
.shopbar__b,.stickybuy__b{
   
  border:0; font-weight:500; letter-spacing:var(--track-label);
}
.skip{  }

/* ==========================================================================
   12c · THE HERO GROUND
   A full screen of madder at 52% aina opacity, which is rule 4 broken as
   completely as it can be: the one red is sealing wax, not paint, and here it
   was the entire first frame. It also collided with the ad: the creative is
   built on --ground-1, so she tapped a near-black ad and landed on a red page.
   That mismatch reads as a different website and costs her between tap and
   paint, which is the most expensive place to lose someone.

   The ground is now the page ground. The red survives where it belongs — a
   deep pool low and off-centre, the way a lamp throws colour onto a wall, so
   the warmth is still there and the object is still the brightest thing on it.
   ========================================================================== */
.ivan{
  
}
.ivan::before{                 /* the mirror, at a whisper, not a sheath */
  opacity:.14 !important;
  background-size:160px 160px !important;
  
}
.ivan::after{                  /* seat the hero into the page below it */
  content:""; position:absolute; left:0; right:0; bottom:0; height:22%;
  
  pointer-events:none;
}
.ivan .d,.ivan h1{ }

/* ==========================================================================
   17 · BRAND PHOTOGRAPHY
   These arrive as bright stock daylight and the house is a dark room, so every
   one is graded down before it ships and then seated here: a hairline frame,
   a vignette that ties the edges into the page, and a warm multiply so the
   image belongs to the same lamp as everything else.

   They are atmosphere. They never carry a provenance claim and never appear on
   a product page. See brand_image() in functions.php.
   ========================================================================== */
.bfig{
  position:relative; margin:0; overflow:hidden;
  
  border:var(--hair) solid var(--rule);
}
.bfig img{
  width:100%; height:100%; object-fit:cover; display:block;
  
}
.bfig::after{                    /* seat it in the page */
  content:""; position:absolute; inset:0; pointer-events:none;
  
}
.bfig--tall{ aspect-ratio:3/4 }
.bfig--wide{ aspect-ratio:16/9 }
.bfig--square{ aspect-ratio:1/1 }

/* the plate treatment, for the one image that carries a section */
.bfig--plate{ padding:clamp(10px,2.6vw,18px); }
.bfig--plate img{ border:var(--hair) solid var(--rule-faint) }

/* No captions. A brand photograph is shown as it is — nothing underneath it
   explaining, qualifying or apologising for it.

   Which changes how the honesty rule is kept, and for the better: it is kept
   by not using a photograph that needs defending. The maker-at-the-wheel frame
   was removed for exactly that reason — it read as our workshop and needed a
   line underneath saying it was not. An image that requires a disclaimer is
   the wrong image. The rule lives in brand_image() where the customer never
   sees it, and in the choosing. */
.bfig figcaption,.bcap{ display:none }

/* a photograph used as a section ground, well under the type */
.photoband{ position:relative; isolation:isolate; overflow:hidden }
.photoband>.bfig{
  position:absolute; inset:0; border:0; z-index:-1;
}
.photoband>.bfig img{ }
.photoband>.bfig::after{
  
}

/* ==========================================================================
   18 · SCALE — the product page and the photo band
   Both faults in the screenshots are the same fault: things sized to fill the
   space available rather than sized to be read.
   ========================================================================== */

/* ---- 18.1 · THE PHOTO BAND -----------------------------------------------
   It was filling the viewport. .photoband had no height of its own, the figure
   inside is absolute inset:0, and the section grew until the copy pushed it —
   so a 1417px photograph was being stretched across a full-bleed band and went
   soft. The picture is now re-exported wider AND the band is given a height,
   because a photograph should be a band across the page, not a second hero.
   The copy is what the section is for. */
.photoband{
  min-height:clamp(380px, 52vh, 560px);
  display:grid; place-items:center;
  padding-block:clamp(56px, 8vw, 96px);
}
.photoband>.bfig{ position:absolute; inset:0; border:0; z-index:-1 }
.photoband>.bfig img{
  width:100%; height:100%; object-fit:cover; object-position:center 42%;
  
}
.photoband .sec__in{ position:relative; z-index:1; max-width:44ch }

/* ---- 18.2 · THE PRODUCT PAGE ---------------------------------------------
   The piece was running 3:4 portrait at the full column width, which on a
   laptop is roughly 790px tall before a word of copy — so the price, the sizes
   and the button all sat below the fold and she scrolled past the argument to
   reach them. It is capped to the viewport now and CONTAINED rather than
   cropped, because a panel mounted whole is the whole point. */
.pdp__stage img{
  max-height:min(62vh, 620px);
  width:100%; height:auto;
  object-fit:contain !important;
  aspect-ratio:auto !important;
}
.pdp__stage{ display:grid; place-items:center; padding:clamp(10px,1.6vw,18px) }
.pdp__thumbs{ margin-top:.6rem; gap:.45rem }
.pdp__thumbs button{ aspect-ratio:1 }

/* Body copy is left-aligned. It was centred, and centred prose in a narrow
   column gives a ragged left edge that the eye has to re-find on every line —
   which is why the bullet list read as four floating fragments with a diamond
   stranded out to the left of each one. Headings may centre. Sentences do not. */
.pdp__buy,
.pdp__sub,
.pdp__bullets,
.pdp__bullets li,
.pdp__ref,
.pdp .size,
.pdp .sizes{ text-align:left }
.pdp__hook{ text-align:left; font-size:clamp(1.6rem,3.2vw,2.5rem); line-height:1.1 }
.pdp__sub{ font-size:1rem; line-height:1.62; margin-top:.9rem; max-width:52ch }

/* the bullets were a grid with a 0.55rem gap that read as 2rem because each
   line was centred and short. Tighter, flush left, diamond against the text. */
.pdp__bullets{ display:grid; gap:.42rem; margin-top:1.1rem }
.pdp__bullets li{ padding-left:1.25rem; font-size:.9rem; line-height:1.5 }
.pdp__bullets li::before{ left:0; top:.55em; width:7px; height:7px }

/* ---- 18.3 · THE SIZE PICKER ----------------------------------------------
   Four options at roughly 120px each is 480px of picker. They are choices, not
   sections. Halved, and the row reads across in one pass: size, then the
   centimetres under it, then the price hard right. */
.pdp .size,.sizes label,.size{
  padding:.9rem 1.15rem !important;
  min-height:0;
  display:grid !important;
  grid-template-columns:22px minmax(0,1fr) auto;   /* khatam · label · price */
  align-items:center; gap:1rem;
  cursor:pointer;
}
.size__l{ display:block; min-width:0 }
.size__n,.size__ft{ font-size:1.02rem; letter-spacing:.06em }
.size__cm{ font-size:.72rem; letter-spacing:.05em; margin-top:.1rem }
.size__p{ font-size:1.15rem }
.size__tag{ font-size:.55rem; padding:.14rem .4rem; margin-left:.45rem }
.sizes{ gap:.5rem !important; margin-top:.9rem !important }

/* ---- 18.4 · THE UPSELL — belt and braces on the capitals ------------------
   v2.0 keyed a form-label style on the bare `label` element and the upsell is
   <label class="upsell"> wrapped round a paragraph, so the prose inherited
   .62rem, .28em tracking and uppercase. The :not(:has()) guard I wrote to fix
   it is doing the right thing in a modern browser and nothing at all in one
   without :has(), which silently invalidates the whole selector list. So the
   guard stays and this states it outright as well. Ugly, and correct. */
.upsell,.upsell *,
.ackrow,.ackrow *{
  text-transform:none !important;
  letter-spacing:normal !important;
  text-align:left !important;
}
.upsell__t{ font-size:.92rem !important; line-height:1.5 !important; }
.upsell__t b{ font-size:.98rem; font-weight:500 }
.upsell__d{ font-size:.84rem !important; line-height:1.55 !important; 
            margin-top:.3rem }
.upsell{ padding:.9rem 1rem; gap:.8rem; align-items:center }
.upsell__p{ font-size:1.08rem }

/* ---- 18.5 · the allocation line and the duties line are one-liners -------- */
.alloc,.dutyline{
  text-align:left; font-size:.92rem; line-height:1.5;
  margin:1.1rem 0 0; 
}
.dutyline b{ }

/* ==========================================================================
   19 · THE SURFACES — where the house actually lives
   The tokens were right and were being spent on plain boxes. A size picker
   rendered as four flat brown rectangles with a hairline is a form fieldset,
   and no amount of correct hex makes a fieldset look like a dealer's room.

   What makes a surface read as expensive on a screen is not colour. It is
     · LIGHT — a lit top edge, as though a lamp is above it, and a dark foot
     · METAL — gold that travels across an edge instead of sitting flat
     · TEXTURE — a real jali under the fill so it is not a painted rectangle
     · ORNAMENT AT THE DECISION — the khatam where the radio dot was

   All four are below, and they are applied to the commerce furniture, which
   is the part she actually looks at.
   ========================================================================== */
:root{
  --jali-lattice:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 48 48'%3E%3Cpath fill='%23A98B4B' fill-rule='evenodd' d='M14.4,0.0L5.5,2.3L10.2,10.2L2.3,5.5L0.0,14.4L-2.3,5.5L-10.2,10.2L-5.5,2.3L-14.4,0.0L-5.5,-2.3L-10.2,-10.2L-2.3,-5.5L-0.0,-14.4L2.3,-5.5L10.2,-10.2L5.5,-2.3ZM62.4,0.0L53.5,2.3L58.2,10.2L50.3,5.5L48.0,14.4L45.7,5.5L37.8,10.2L42.5,2.3L33.6,0.0L42.5,-2.3L37.8,-10.2L45.7,-5.5L48.0,-14.4L50.3,-5.5L58.2,-10.2L53.5,-2.3ZM14.4,48.0L5.5,50.3L10.2,58.2L2.3,53.5L0.0,62.4L-2.3,53.5L-10.2,58.2L-5.5,50.3L-14.4,48.0L-5.5,45.7L-10.2,37.8L-2.3,42.5L-0.0,33.6L2.3,42.5L10.2,37.8L5.5,45.7ZM62.4,48.0L53.5,50.3L58.2,58.2L50.3,53.5L48.0,62.4L45.7,53.5L37.8,58.2L42.5,50.3L33.6,48.0L42.5,45.7L37.8,37.8L45.7,42.5L48.0,33.6L50.3,42.5L58.2,37.8L53.5,45.7ZM38.4,24.0L29.5,26.3L34.2,34.2L26.3,29.5L24.0,38.4L21.7,29.5L13.8,34.2L18.5,26.3L9.6,24.0L18.5,21.7L13.8,13.8L21.7,18.5L24.0,9.6L26.3,18.5L34.2,13.8L29.5,21.7ZM30.4,2.7L26.0,2.0L26.7,6.4L24.0,2.8L21.3,6.4L22.0,2.0L17.6,2.7L21.2,0.0L17.6,-2.7L22.0,-2.0L21.3,-6.4L24.0,-2.8L26.7,-6.4L26.0,-2.0L30.4,-2.7L26.8,-0.0ZM6.4,26.7L2.0,26.0L2.7,30.4L0.0,26.8L-2.7,30.4L-2.0,26.0L-6.4,26.7L-2.8,24.0L-6.4,21.3L-2.0,22.0L-2.7,17.6L-0.0,21.2L2.7,17.6L2.0,22.0L6.4,21.3L2.8,24.0ZM54.4,26.7L50.0,26.0L50.7,30.4L48.0,26.8L45.3,30.4L46.0,26.0L41.6,26.7L45.2,24.0L41.6,21.3L46.0,22.0L45.3,17.6L48.0,21.2L50.7,17.6L50.0,22.0L54.4,21.3L50.8,24.0ZM30.4,50.7L26.0,50.0L26.7,54.4L24.0,50.8L21.3,54.4L22.0,50.0L17.6,50.7L21.2,48.0L17.6,45.3L22.0,46.0L21.3,41.6L24.0,45.2L26.7,41.6L26.0,46.0L30.4,45.3L26.8,48.0Z'/%3E%3C/svg%3E");
  --jali-fine:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='96' viewBox='0 0 96 96'%3E%3Cpath fill='%23A98B4B' fill-rule='evenodd' d='M17.8,0.0L6.8,2.8L12.6,12.6L2.8,6.8L0.0,17.8L-2.8,6.8L-12.6,12.6L-6.8,2.8L-17.8,0.0L-6.8,-2.8L-12.6,-12.6L-2.8,-6.8L-0.0,-17.8L2.8,-6.8L12.6,-12.6L6.8,-2.8ZM113.8,0.0L102.8,2.8L108.6,12.6L98.8,6.8L96.0,17.8L93.2,6.8L83.4,12.6L89.2,2.8L78.2,0.0L89.2,-2.8L83.4,-12.6L93.2,-6.8L96.0,-17.8L98.8,-6.8L108.6,-12.6L102.8,-2.8ZM17.8,96.0L6.8,98.8L12.6,108.6L2.8,102.8L0.0,113.8L-2.8,102.8L-12.6,108.6L-6.8,98.8L-17.8,96.0L-6.8,93.2L-12.6,83.4L-2.8,89.2L-0.0,78.2L2.8,89.2L12.6,83.4L6.8,93.2ZM113.8,96.0L102.8,98.8L108.6,108.6L98.8,102.8L96.0,113.8L93.2,102.8L83.4,108.6L89.2,98.8L78.2,96.0L89.2,93.2L83.4,83.4L93.2,89.2L96.0,78.2L98.8,89.2L108.6,83.4L102.8,93.2ZM65.8,48.0L54.8,50.8L60.6,60.6L50.8,54.8L48.0,65.8L45.2,54.8L35.4,60.6L41.2,50.8L30.2,48.0L41.2,45.2L35.4,35.4L45.2,41.2L48.0,30.2L50.8,41.2L60.6,35.4L54.8,45.2ZM65.8,0.0L54.8,2.8L60.6,12.6L50.8,6.8L48.0,17.8L45.2,6.8L35.4,12.6L41.2,2.8L30.2,0.0L41.2,-2.8L35.4,-12.6L45.2,-6.8L48.0,-17.8L50.8,-6.8L60.6,-12.6L54.8,-2.8ZM17.8,48.0L6.8,50.8L12.6,60.6L2.8,54.8L0.0,65.8L-2.8,54.8L-12.6,60.6L-6.8,50.8L-17.8,48.0L-6.8,45.2L-12.6,35.4L-2.8,41.2L-0.0,30.2L2.8,41.2L12.6,35.4L6.8,45.2ZM113.8,48.0L102.8,50.8L108.6,60.6L98.8,54.8L96.0,65.8L93.2,54.8L83.4,60.6L89.2,50.8L78.2,48.0L89.2,45.2L83.4,35.4L93.2,41.2L96.0,30.2L98.8,41.2L108.6,35.4L102.8,45.2ZM65.8,96.0L54.8,98.8L60.6,108.6L50.8,102.8L48.0,113.8L45.2,102.8L35.4,108.6L41.2,98.8L30.2,96.0L41.2,93.2L35.4,83.4L45.2,89.2L48.0,78.2L50.8,89.2L60.6,83.4L54.8,93.2ZM30.4,26.6L26.0,26.0L26.6,30.4L24.0,26.9L21.4,30.4L22.0,26.0L17.6,26.6L21.1,24.0L17.6,21.4L22.0,22.0L21.4,17.6L24.0,21.1L26.6,17.6L26.0,22.0L30.4,21.4L26.9,24.0ZM78.4,26.6L74.0,26.0L74.6,30.4L72.0,26.9L69.4,30.4L70.0,26.0L65.6,26.6L69.1,24.0L65.6,21.4L70.0,22.0L69.4,17.6L72.0,21.1L74.6,17.6L74.0,22.0L78.4,21.4L74.9,24.0ZM30.4,74.6L26.0,74.0L26.6,78.4L24.0,74.9L21.4,78.4L22.0,74.0L17.6,74.6L21.1,72.0L17.6,69.4L22.0,70.0L21.4,65.6L24.0,69.1L26.6,65.6L26.0,70.0L30.4,69.4L26.9,72.0ZM78.4,74.6L74.0,74.0L74.6,78.4L72.0,74.9L69.4,78.4L70.0,74.0L65.6,74.6L69.1,72.0L65.6,69.4L70.0,70.0L69.4,65.6L72.0,69.1L74.6,65.6L74.0,70.0L78.4,69.4L74.9,72.0Z'/%3E%3C/svg%3E");

  /* gold as a metal: dark at the edges, hot through the middle */
  --metal:linear-gradient(135deg,
      var(--gold-0) 0%, var(--gold-2) 22%, var(--gold-4) 44%,
      var(--gold-2) 62%, var(--gold-0) 100%);
  --metal-soft:linear-gradient(135deg,
      rgba(74,54,24,.55) 0%, rgba(169,139,75,.75) 30%, rgba(240,220,168,.95) 50%,
      rgba(169,139,75,.75) 70%, rgba(74,54,24,.55) 100%);
}

/* -------------------------------------------------------- the base surface */
.surface,
.pdp .size, .sizes label, .size,
.upsell,
.offercard,
.folio__mount{
  position:relative;
  
  border:var(--hair) solid var(--gold-0);
  isolation:isolate;
  transition:border-color .45s var(--ease), background .45s var(--ease),
             transform .45s var(--ease), box-shadow .45s var(--ease);
}
/* the jali, under everything, at the edge of visibility */
.surface::before,
.pdp .size::before, .sizes label::before, .size::before,
.upsell::before,
.offercard::before{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  
  background-size:48px 48px;
  opacity:.055;
  transition:opacity .5s var(--ease);
}
/* the lit top edge — one hairline of metal where the lamp falls */
.surface::after,
.pdp .size::after, .sizes label::after, .size::after,
.upsell::after,
.offercard::after{
  content:""; position:absolute; left:0; right:0; top:0; height:1px;
   opacity:.45; pointer-events:none;
  transition:opacity .5s var(--ease);
}

/* ---------------------------------------------------------- the lifted state */
@media (hover:hover){
  .pdp .size:hover, .sizes label:hover, .size:hover, .upsell:hover{
    
    transform:translateY(-1px);
  }
  .pdp .size:hover::before, .size:hover::before, .upsell:hover::before{ opacity:.09 }
  .pdp .size:hover::after,  .size:hover::after,  .upsell:hover::after{ opacity:.8 }
}

/* ---------------------------------------------------------- :has() FALLBACK
   Every chosen-state rule below is written TWICE: once on a class that JS puts
   on the label, and once on :has(). They are separate blocks on purpose and
   must never be merged into one comma list — an unsupported :has() invalidates
   the WHOLE selector list it appears in, which is exactly how the upsell
   shipped in capitals for two days. site.js mirrors :checked onto .is-on.
   ========================================================================== */
.size.is-on,.sizes label.is-on,.upsell.is-on{
  
  
  
}
.size.is-on::before,.sizes label.is-on::before,.upsell.is-on::before{ opacity:.12 }
.size.is-on::after,.sizes label.is-on::after,.upsell.is-on::after{ opacity:1 }
.size.is-on .size__dot,.upsell.is-on .upsell__box{ }
.size.is-on .size__dot::after,.upsell.is-on .upsell__box::after{
  opacity:1; transform:scale(1) rotate(0deg);
}

/* --------------------------------------------------------- the chosen state
   It was a slightly lighter brown, which reads as disabled rather than
   selected. A chosen thing should look LIT: the jali comes up, the metal edge
   fires, and a warm pool sits behind it. */
.size:has(input:checked),
.sizes label:has(input:checked),
.size.is-on,
.upsell:has(input:checked){
  
  
  
}
.size:has(input:checked)::before,
.sizes label:has(input:checked)::before,
.upsell:has(input:checked)::before{ opacity:.12 }
.size:has(input:checked)::after,
.sizes label:has(input:checked)::after,
.upsell:has(input:checked)::after{ opacity:1 }

/* ------------------------------------------------------ the khatam selector
   The eight-pointed star replaces the radio dot. It is the house mark, it is
   the one place ornament belongs in the buy column, and it turns the moment of
   choosing into the moment the ornament appears. */
.size input[type=radio],
.sizes input[type=radio],
.upsell input[type=checkbox]{
  position:absolute; opacity:0; width:0; height:0; pointer-events:none;
}
.size__dot,.size__mark,.upsell__box{
  position:relative; flex:none;
  width:22px; height:22px; display:block;
  border:var(--hair) solid var(--gold-1);
  
  transition:border-color .4s var(--ease);
}
.size__dot::after,.size__mark::after,.upsell__box::after{
  content:""; position:absolute; inset:3px;
  
  clip-path:polygon(50% 0%,61% 21%,85% 15%,79% 39%,100% 50%,79% 61%,85% 85%,
                    61% 79%,50% 100%,39% 79%,15% 85%,21% 61%,0% 50%,21% 39%,
                    15% 15%,39% 21%);
  opacity:0; transform:scale(.35) rotate(-45deg);
  transition:opacity .42s var(--ease), transform .52s var(--ease-long);
}
.size:has(input:checked) .size__dot,
.size:has(input:checked) .size__mark,
.upsell:has(input:checked) .upsell__box{ }
.size:has(input:checked) .size__dot::after,
.size:has(input:checked) .size__mark::after,
.upsell:has(input:checked) .upsell__box::after{
  opacity:1; transform:scale(1) rotate(0deg);
}
input:focus-visible ~ .size__dot,
input:focus-visible ~ .size__mark,
input:focus-visible ~ .upsell__box{ outline:2px solid var(--gold-3); outline-offset:3px }

/* ---------------------------------------------- the free-delivery upsell
   When the lift crosses the threshold the second piece is genuinely free and
   the card says so. It is the only surface on the page allowed to glow. */
.upsell--free{
  
  
}
.upsell--free .upsell__p{
  font-family:var(--display); font-style:italic;
   font-size:1.24rem;
}
.upsell--free::after{ opacity:.9 }

/* ---------------------------------------------------- the metal-edged button
   The buy button was a flat gold fill. Flat gold is paint; a gradient that
   runs across it is a struck surface. */
.btn--fill,.btn--buy,.cta--buy,.cta,.shopbar__b,.stickybuy__b{
  position:relative; overflow:hidden;
  
  background-size:200% 100% !important;
  
  border:0 !important;
  transition:background-position .9s var(--ease-long), filter .4s var(--ease);
}
.btn--fill:hover,.btn--buy:hover,.cta:hover,.shopbar__b:hover{
  background-position:100% 0 !important;   /* the light travels across it */
  
}
/* the outline button gets a metal frame rather than a flat hairline */
.btn:not(.btn--fill):not(.btn--buy),.ivan__cta{
  position:relative; 
}
.btn:not(.btn--fill):not(.btn--buy)::before,.ivan__cta::before{
  content:""; position:absolute; inset:0; padding:1px; pointer-events:none;
  
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor; mask-composite:exclude;
  opacity:.75; transition:opacity .4s var(--ease);
}
.btn:not(.btn--fill):not(.btn--buy):hover::before,.ivan__cta:hover::before{ opacity:1 }

/* ------------------------------------------------------------- the plate
   The product mount gets a jali margin and a metal inner line, so the piece
   is mounted rather than pasted. */
.pdp__stage{
  
  
}
.pdp__stage::before{
  content:""; position:absolute; inset:0; pointer-events:none;
   background-size:96px 96px; opacity:.05;
}
.pdp__stage::after{
  content:""; position:absolute; inset:10px; pointer-events:none;
  border:var(--hair) solid rgba(169,139,75,.22);
}
.pdp__thumbs button{  transition:border-color .35s var(--ease) }
.pdp__thumbs button[aria-current="true"]{ }

/* ==========================================================================
   20 · MOTION — a house moves slowly
   Nothing bounces, nothing springs. Everything settles.
   ========================================================================== */
@keyframes st-rise{ from{opacity:0;transform:translateY(18px)} to{opacity:1;transform:none} }
@keyframes st-glow{ 0%,100%{opacity:.4} 50%{opacity:.85} }
@keyframes st-sheen{ 0%{background-position:0 0} 100%{background-position:200% 0} }

.rv{ opacity:0; transform:translateY(18px);
     transition:opacity .9s var(--ease), transform 1s var(--ease-long) }
.rv.is-in,.no-js .rv{ opacity:1; transform:none }

/* the picker settles in, one row after the next */
.sizes label,.pdp .size{ animation:st-rise .7s var(--ease-long) both }
.sizes label:nth-child(1),.pdp .size:nth-child(1){ animation-delay:.04s }
.sizes label:nth-child(2),.pdp .size:nth-child(2){ animation-delay:.10s }
.sizes label:nth-child(3),.pdp .size:nth-child(3){ animation-delay:.16s }
.sizes label:nth-child(4),.pdp .size:nth-child(4){ animation-delay:.22s }
.sizes label:nth-child(5),.pdp .size:nth-child(5){ animation-delay:.28s }

/* the free-delivery card breathes, very slowly, once it is on the page */
.upsell--free::after{ animation:st-glow 4.6s ease-in-out infinite }

/* the khatam dividers turn a quarter turn when their section arrives */
.rule-khatam svg{ transition:transform 1.4s var(--ease-long) }
.rv.is-in .rule-khatam svg,.is-in>.rule-khatam svg{ transform:rotate(90deg) }

@media (prefers-reduced-motion:reduce){
  .sizes label,.pdp .size{ animation:none }
  .upsell--free::after{ animation:none }
  .rule-khatam svg{ transition:none }
  .btn--fill,.cta{ transition:none }
}

/* ==========================================================================
   13 · THE BUY BAR — the one piece of ecommerce furniture that earns its space
   ========================================================================== */
.shopbar,.stickybuy{
  z-index:var(--z-shopbar) !important;
  
   
  border-top:var(--hair) solid var(--rule-2);
  padding-bottom:calc(.7rem + env(safe-area-inset-bottom,0px));
}
.shopbar__t{ font-family:var(--display); }
.shopbar__s{ }
.shopbar__b{  }

/* ==========================================================================
   14 · FORMS — the cut-to-measure input is the highest-intent surface here
   ========================================================================== */
input,select,textarea{
  font-family:var(--body); font-size:16px;   /* 16px or iOS zooms on focus */
  
  
  border:var(--hair) solid var(--rule);
  padding:.85rem 1rem; min-height:48px; width:100%;
  border-radius:0;
  transition:border-color .3s var(--ease);
}
input:focus,select:focus,textarea:focus{ outline:none; }
input::placeholder,textarea::placeholder{ }
/* CTO, 22 Sep — my bug, introduced in v2.0. This read `label, .fld>span`,
   which is a bare element selector, and the product page wraps its upsell in
   <label class="upsell"> around a full paragraph of prose. The paragraph
   inherited .62rem, .28em tracking and uppercase, and rendered as an
   unreadable centred block of capitals on the highest-value surface on the
   site. A form-label style must never be keyed on the element alone: a label
   is a wrapper as often as it is a caption. */
.fld>span,
label.lbl,
label:not(:has(p)):not(:has(input[type=checkbox])):not(.upsell):not(.ackrow):not(.size){
  display:block; font-family:var(--body); font-size:var(--t-label);
  letter-spacing:var(--track-label); text-transform:uppercase;
   margin-bottom:.5rem;
}
/* wrapping labels keep normal prose */
label.upsell,label.ackrow,label.size{
  text-transform:none; letter-spacing:normal;
  font-size:var(--t-body);  margin-bottom:0;
}
label.upsell .upsell__t{ font-size:.9rem; line-height:1.55; text-align:left }
label.upsell .upsell__d{ font-size:.82rem; line-height:1.6; }
:focus-visible{ outline:2px solid var(--gold-3); outline-offset:3px }

/* ==========================================================================
   15 · TABLES, FOOTER, ODDS
   ========================================================================== */
table{ width:100%; border-collapse:collapse; font-size:var(--t-small) }
th,td{ text-align:left; padding:.8rem 1rem; border-bottom:var(--hair) solid var(--rule) }
th{ font-size:var(--t-label); letter-spacing:var(--track-label); text-transform:uppercase;
     font-weight:400 }
.foot,footer{ border-top:var(--hair) solid var(--rule);  font-size:var(--t-small) }
.foot a,footer a{ }
.foot a:hover,footer a:hover{ }
.crumbs{ font-size:var(--t-label); letter-spacing:.18em; text-transform:uppercase; }
.crumbs a{ }
body.home .crumbs,.is-home .crumbs{ display:none }   /* a breadcrumb on the
                                                        homepage told her she
                                                        was somewhere else */
.skip{
  position:absolute; left:-9999px;
    padding:1rem 1.5rem; z-index:999;
}
.skip:focus{ left:var(--gutter); top:var(--gutter) }

/* ==========================================================================
   16 · TOUCH, MOTION, AND THE THINGS THAT BROKE ON A PHONE
   ========================================================================== */
a,button,.btn,.cta,summary,.size,.pick,input[type=submit]{ min-height:48px }
.head__nav a,.foot a,footer a,.crumbs a{ min-height:44px; display:inline-flex; align-items:center }
pre,table{ max-width:100%; overflow-x:auto; -webkit-overflow-scrolling:touch }

@media (hover:none){
  .folio:hover .folio__cloth{ transform:none }
  .folio:hover .folio__mount{ }
  a:active,button:active,.btn:active,.folio:active{ opacity:.74 }
  .btn:hover,.cta:hover{ }
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
  .rv{ opacity:1 !important; transform:none !important }
  .drawer{ transition:none }
}
/* the reveal — once, slowly, and never blocking content if JS fails */
.rv{ opacity:0; transform:translateY(16px); transition:opacity .8s var(--ease),transform .9s var(--ease-long) }
.rv.is-in,.no-js .rv{ opacity:1; transform:none }


/* ==========================================================================
   THE STACK — asserted last, because it has been broken three times
   head 40 · shopbar 50 · consent 60 · drawer 80 · veil 100
   A cookie notice above the buy button is a conversion bug in a legal costume,
   and a drawer under the header is a menu nobody can use. Both shipped once.
   Nothing below may be raised without moving everything above it.
   ========================================================================== */
.head    { z-index: 40 !important }
.shopbar,
.stickybuy { z-index: 50 !important }
.consent { z-index: 60 !important }
.drawer  { z-index: 80 !important }
.agate,
.gate    { z-index: 90 !important }
.veil    { z-index: 100 !important }
