:root{
  --paper:#E4DCCB;      /* oat — warm natural-dye ground */
  --ink:#2A2620;        /* warm near-black — body */
  --indigo:#2B3B57;     /* indigo vat — deep ground */
  --weld:#B98A2E;       /* weld ochre — fine accent */
  --madder:#A6503C;     /* warm madder — selvedge / links */
  --madder-d:#8A4231;   /* deeper madder — the woven stripe */
  --iron:#6B6152;       /* warm grey — secondary text */
  --ash:#C9BEA8;        /* warm oat — rules, cards */
  --paper-soft:#DDD4C1;
  --chalk:#F4F0E7;      /* lighter than the page — used for type on the menu */
  --menu:#102820;       /* the header block */
  --pool:#BCC8C3;       /* the lit ground behind copy on a photograph */
  --sel:clamp(26px,5vw,40px);                      /* selvedge width */
  --gap:calc(var(--sel) + clamp(18px,4vw,40px));   /* content offset that clears it */
  --tab:52px;                                      /* the fixed utility tabs are this wide at
                                                      every viewport — measured, not guessed */
  /* Right margin. It has to clear the tabs, and the old clamp bottomed out at
     44px on phones while the tabs are 52px, so page text ran up to 8px beneath
     them on every page. The floor is now the tab width plus a little air. */
  --dsel:max(calc(var(--tab) + 8px),clamp(44px,5vw,62px));
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;background:var(--paper);color:var(--ink);
  padding-left:var(--gap);padding-right:var(--dsel);
  overflow-x:clip;
  font-family:"Spectral",Georgia,serif;font-weight:400;
  font-optical-sizing:auto;line-height:1.55;
  -webkit-font-smoothing:antialiased;
}
.mono{font-family:"IBM Plex Mono",ui-monospace,monospace}
a{color:inherit}
img{max-width:100%}

/* ---------- layout ---------- */
.wrap{max-width:1080px;margin:0 auto;padding:0 28px}
.page{display:block}

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

/* ---------- full-bleed ------------------------------------------------------
   ONE rule, used by every edge-to-edge section. Do not invent a second one.

   The element's background reaches the true viewport edges and runs UNDER the
   fixed selvedge (left) and utility tabs (right), both z-index 60. Its contents
   are then pushed back inside exactly the gutters the body already uses, so the
   text lands in the same place it did before and nothing can sit beneath either
   fixture. Never use 100vw here: that counts the scrollbar and overflows.

   Add .bleed-flush when the content IS the full-width thing — an edge-to-edge
   photograph — and must not be padded back in.

   Before this was centralised, .bleed cancelled only the LEFT inset and stopped
   at the selvedge, so every blue band and the footer left a bare strip of paper
   down the right-hand side while the W01 band, which cancelled both, did not.  */
.bleed{
  margin-left:calc(-1 * var(--gap));
  margin-right:calc(-1 * var(--dsel));
  padding-left:var(--gap);
  padding-right:var(--dsel);
}
.bleed-flush{padding-left:0;padding-right:0}

/* iOS Safari does not give the page the whole screen: the layout viewport stops
   below the status bar and above the toolbar, so a fixed element at top:0 /
   bottom:0 stops there too and the selvedge appeared to be cut off at both ends.
   Safari paints those two strips with the CANVAS background, so drawing the
   selvedge's own stripe down the left of the canvas makes it read as continuous
   without touching the viewport or the safe areas. Everywhere else the body
   covers this completely, so it is invisible.
   Setting a background here also stops the body's from propagating to the
   canvas, which is why paper is repeated as the second layer. */
html{
  background:
    repeating-linear-gradient(0deg,var(--madder) 0 6px,var(--madder-d) 6px 12px)
      left top / var(--sel) 100% repeat-y,
    var(--paper);
}

/* ---------- header ---------- */
/* The header is an island, not a band. It stays in flow (so it still reserves
   its own space and nothing slides under it), but the visible shape is .bar:
   an opaque rounded block inset clear of the selvedge on the left. Opaque
   means no backdrop-filter, which is where iOS Safari did its worst work. The
   top inset respects the notch through env(safe-area-inset-top). */
header{
  position:sticky;
  top:calc(env(safe-area-inset-top, 0px) + 10px);
  z-index:40;
  background:none;
  border:0;
  /* body already insets the page: --gap on the left to clear the selvedge,
     --dsel on the right to clear the decide tab. The header was adding its own
     clearance on top of that, so on a 375px screen the island came out 229px
     wide instead of 333. Pull the page padding back, then apply only what the
     header itself needs — the decide tab sits at mid-height and never reaches
     up here, so the right side only wants a little air. */
  margin-left:calc(-1 * var(--gap));
  margin-right:calc(-1 * var(--dsel));
  padding:10px 0 0;
  padding-left:calc(var(--sel) + clamp(6px,1.6vw,12px));
  padding-right:clamp(6px,1.6vw,12px);
}
.bar{display:flex;align-items:center;justify-content:space-between;
  gap:10px;padding:13px 16px;max-width:1180px;margin:0 auto;flex-wrap:nowrap;
  /* --menu at 99%. The 1% is a breath, not a window: nothing legible shows
     through, and contrast is unchanged. No backdrop-filter — at this alpha
     there is nothing to blur, and it was the expensive part on iOS. */
  background-color:rgba(16,40,32,.99);
  /* a fine vertical rib, plus a sheen down the face. The sheen is what gives
     the block depth; the rib just stops it reading as a flat slab. */
  background-image:
    linear-gradient(180deg, rgba(244,240,231,.075) 0%, rgba(244,240,231,.012) 46%,
                            rgba(0,0,0,.10) 100%),
    repeating-linear-gradient(90deg, rgba(244,240,231,.045) 0 1px, transparent 1px 2px);
  border:0;
  border-radius:17px;
  /* Volume is four things at once: a lit top arris, a dark underside, a tight
     contact shadow and a broad ambient one. Any single layer reads as flat. */
  box-shadow:
    inset 0 1px 0 rgba(244,240,231,.17),
    inset 0 -1px 0 rgba(0,0,0,.40),
    0 1px 2px rgba(16,32,26,.24),
    0 6px 14px -6px rgba(16,32,26,.28),
    0 22px 44px -24px rgba(16,32,26,.46);
  transition:box-shadow .3s ease;
}
/* once you are reading, it lifts a little further off the page */
header.settled .bar{
  box-shadow:
    inset 0 1px 0 rgba(244,240,231,.17),
    inset 0 -1px 0 rgba(0,0,0,.40),
    0 1px 2px rgba(16,32,26,.28),
    0 8px 18px -6px rgba(16,32,26,.34),
    0 30px 56px -26px rgba(16,32,26,.56);
}
.brand{font-weight:500;font-size:1.06rem;letter-spacing:.035em;cursor:pointer;
  background:none;border:0;color:var(--chalk);font-family:"Spectral",serif;
  white-space:nowrap;padding:0;text-decoration:none}
/* madder is 2.75:1 on ink and unreadable; weld clears 4.8:1 and keeps an accent */
.brand .amp{color:var(--weld);font-style:italic;font-weight:400}
nav{display:flex;flex-wrap:nowrap;gap:4px;align-items:center;
  /* One lane at every width. Past the edge the nav scrolls rather than
     wrapping; the mask softens both ends so a half-cut word reads as "there
     is more" instead of as a mistake. */
  overflow-x:auto;overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;
  scrollbar-width:none;-ms-overflow-style:none;
}
nav::-webkit-scrollbar{display:none}
.brand{flex:0 0 auto}

/* The soft ends are painted over the scroller, not masked into it. A mask on
   nav would also clip .drop — it applies to every descendant's painted output,
   and the menu simply vanished. These sit above the links and below the menu,
   and pass clicks through. */
/* flex-end was right when the wordmark held the left of the bar. With the
   wordmark gone there is nothing to push against, so the links bunched at the
   far end with dead space in front of them. */
.navwrap{position:relative;min-width:0;flex:1 1 auto;display:flex;justify-content:flex-start}
nav{width:100%}
/* A painted strip can never match a surface that has a sheen on it — the strip
   is flat and the block is not, so its edge shows as a band. Fade the links
   instead, with a mask, and only at the end that actually has something behind
   it: site.js sets .fade-l / .fade-r from scrollLeft. */
nav{--fl:0px;--fr:0px;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 var(--fl),#000 calc(100% - var(--fr)),transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 var(--fl),#000 calc(100% - var(--fr)),transparent 100%);
}
nav.fade-l{--fl:13px}
nav.fade-r{--fr:13px}
.nav-link{font-family:"IBM Plex Mono",monospace;font-size:.70rem;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ash);
  background:none;border:0;cursor:pointer;
  padding:9px 11px;position:relative;transition:color .18s ease;white-space:nowrap;
  text-align:center}
/* A drawn rule rather than a box. ::before, because ::after already carries
   the submenu chevron. Same vocabulary as the selvedge and the hem frames. */
.nav-link::before{content:"";position:absolute;left:11px;right:11px;bottom:4px;
  height:1.5px;background:var(--weld);transform:scaleX(0);transform-origin:left;
  transition:transform .24s cubic-bezier(.2,.7,.3,1)}
.nav-link:hover,.nav-link:focus-visible{color:var(--chalk);outline:none}
.nav-link:hover::before,.nav-link:focus-visible::before,
.navgroup.open>.nav-link::before{transform:scaleX(1)}
.nav-link.active{color:var(--chalk)}
.nav-link.active::before{transform:scaleX(1);background:var(--weld)}

/* ---------- nav : a plain dropdown under each parent, no drawn lines ---------- */
.navgroup{position:relative;display:inline-block}
/* Home holds the left edge on its own; auto margin pushes everything after it
   to the right, so the five links stay a tight group. Below 1000px the nav
   overflows and is a scroller — free space is negative, so the auto margin
   resolves to zero and this rule quietly does nothing. */
.nav-home{display:inline-flex;align-items:center;padding:9px 10px;margin-right:auto}
.nav-home svg{display:block}
.nav-home::before{left:10px;right:10px}
/* the label goes to the page, the arrow opens the list */
.navgroup.has-submenu{display:inline-flex;align-items:center;gap:0}
.navgroup.has-submenu>.nav-link{padding-right:4px}
.navgroup.has-submenu>.nav-link::before{right:4px}   /* the rule follows the padding in */
.drop-toggle{display:inline-flex;align-items:center;justify-content:center;
  background:none;border:0;cursor:pointer;color:var(--ash);
  padding:9px 10px 9px 4px;margin:0;line-height:0;transition:color .18s ease}
.drop-toggle svg{display:block;transition:transform .22s cubic-bezier(.2,.7,.3,1)}
.drop-toggle:hover,.drop-toggle:focus-visible{color:var(--chalk);outline:none}
.drop-toggle[aria-expanded="true"]{color:var(--chalk)}
.drop-toggle[aria-expanded="true"] svg{transform:rotate(180deg)}
.drop{
  /* fixed, not absolute: the nav is a horizontal scroller now, and an
     absolutely positioned child would be clipped by its overflow. site.js
     places this from the parent link's box. */
  position:fixed;min-width:190px;z-index:56;
  display:none;flex-direction:column;padding:6px 0;
  background-color:rgba(16,40,32,.99);border:0;border-radius:14px;
  background-image:
    linear-gradient(180deg, rgba(244,240,231,.055) 0%, rgba(244,240,231,.010) 46%,
                            rgba(0,0,0,.09) 100%),
    repeating-linear-gradient(90deg, rgba(244,240,231,.045) 0 1px, transparent 1px 2px);
  box-shadow:inset 0 1px 0 rgba(244,240,231,.14),0 24px 44px -24px rgba(16,32,26,.6);
  /* no gap to the parent link: a gap falls outside .navgroup, and the pointer
     crossing it would close the menu on the way down. Rounded corners need the
     clip, or a hovered first/last item squares them off again. */
  overflow:hidden;
}
/* :hover is the no-JS fallback. Keyboard and touch go through .open, set by
   site.js — :focus-within would reopen the menu the instant Escape returned
   focus to the trigger. */
/* site.js moves .drop to the end of <body> so the nav mask cannot clip it and
   the side tabs cannot stack over it. Shown by class, not by descendant. */
.drop{display:none}
.drop.open{display:flex}
/* Only Windows has a genuine submenu. Mark that group in the HTML and give it
   a quiet desktop-only cue; the touch nav exposes its destinations directly. */
@media all{
  .navgroup.has-submenu>.nav-link::after{display:none}
  .unused-chevron::after{
    content:"";display:inline-block;width:5px;height:5px;margin-left:7px;
    border-right:1px solid currentColor;border-bottom:1px solid currentColor;
    opacity:.65;transform:translateY(-2px) rotate(45deg);
  }
}
/* Touch devices have no hover, so the first tap was being spent revealing the
   dropdown and a second was needed to follow a link. There, the menu is driven
   by an explicit .open class set in polish.js instead. */
@media (hover:none), (max-width:1000px){
  /* No hover means no menu: site.js lifts the real child links up into the
     scrolling nav so every destination is a single tap. Hidden here as well so
     nothing flashes before the script runs.
     The width case matters just as much on a desktop with a mouse: below
     1000px the nav becomes a horizontal scroll strip, and a scrolling box
     clips whatever hangs out of it, so the dropdown was cut off at the
     header edge. */
}
.nav-sub{opacity:.82}
.drop a{
  font-family:"Spectral",serif;font-size:.96rem;color:var(--ash);
  text-decoration:none;padding:8px 18px;white-space:nowrap;transition:.16s;
}
.drop a:hover{color:var(--chalk);background:rgba(244,240,231,.09)}
.mobonly{display:none}

/* ---------- right edge : help me decide + whatsapp, stacked ---------- */
.floatband{
  position:fixed;right:0;top:50%;transform:translateY(-50%);z-index:60;
  display:flex;flex-direction:column;align-items:flex-end;gap:10px;
}
.floatband .decideband{position:static;transform:none}
/* weld ochre — the one gold in the palette. Paper type on it only reaches
   2.3:1, so the label is --ink; that pairing measures 4.8:1. */
.whatsband{
  display:flex;align-items:center;justify-content:center;cursor:pointer;
  padding:22px 15px;border:1.5px solid var(--weld);border-right:0;
  background:var(--weld);transition:.2s;text-decoration:none;
  box-shadow:-10px 0 32px -16px rgba(42,38,32,.55);
}
.whatsband span{
  writing-mode:vertical-rl;font-family:"IBM Plex Mono",monospace;
  font-size:.86rem;font-weight:500;
  letter-spacing:.24em;text-transform:uppercase;color:var(--ink);
  white-space:nowrap;transition:.2s}
.whatsband:hover{background:var(--madder);border-color:var(--madder);padding-right:19px}
.whatsband:hover span{color:var(--paper)}

.decideband{
  position:fixed;right:0;top:50%;transform:translateY(-50%);z-index:60;
  display:flex;align-items:center;justify-content:center;cursor:pointer;
  padding:34px 15px;border:1.5px solid var(--indigo);border-right:0;
  background:var(--indigo);transition:.2s;text-decoration:none;
  box-shadow:-10px 0 32px -16px rgba(42,38,32,.55);
}
.decideband span{
  writing-mode:vertical-rl;font-family:"IBM Plex Mono",monospace;
  font-size:.86rem;font-weight:500;
  letter-spacing:.24em;text-transform:uppercase;color:var(--paper);
  white-space:nowrap;transition:.2s}
.decideband:hover{background:var(--madder);border-color:var(--madder);padding-right:19px}
.decideband.active{background:var(--madder);border-color:var(--madder)}

/* ---------- selvedge : woven madder band, full height, above every page ---------- */
.selvedge{
  text-decoration:none;cursor:pointer;transition:filter .2s ease;
  position:fixed;left:0;top:0;bottom:0;width:var(--sel);z-index:60;
  background:repeating-linear-gradient(0deg,var(--madder) 0 6px,var(--madder-d) 6px 12px);
  display:flex;align-items:center;justify-content:center;
}
.selvedge::after{ /* frayed, stitched outer edge */
  content:"";position:absolute;right:-4px;top:0;bottom:0;width:4px;
  background:repeating-linear-gradient(0deg,transparent 0 3px,rgba(158,82,64,.5) 3px 6px);
}
.selvedge:hover,.selvedge:focus-visible{filter:brightness(1.12)}
.selvedge:focus-visible{outline:2px solid var(--chalk);outline-offset:-3px}
.selvedge span{
  writing-mode:vertical-rl;transform:rotate(180deg);
  font-family:"IBM Plex Mono",monospace;font-size:.6rem;letter-spacing:.4em;
  text-transform:uppercase;color:var(--paper);white-space:nowrap;opacity:.92;
}

/* ---------- hero ---------- */
.hero{position:relative;overflow:hidden}
.hero-inner{max-width:1080px;margin:0 auto;padding:88px 28px 72px}
.eyebrow{font-family:"IBM Plex Mono",monospace;font-size:.7rem;letter-spacing:.2em;
  text-transform:uppercase;color:var(--iron)}
.hero h1{font-weight:300;font-size:clamp(2.5rem,6vw,4.4rem);line-height:1.04;
  letter-spacing:-.01em;margin:.55em 0 .1em}
.hero h1 .amp{color:var(--madder);font-style:italic}
.lede{font-size:clamp(1.05rem,2vw,1.32rem);font-weight:300;max-width:34ch;
  color:var(--ink);margin:.7em 0 0}
.hero .sub{max-width:52ch;color:var(--iron);font-weight:400;margin:1.1em 0 0;
  font-size:1.02rem}
.cta-row{display:flex;flex-wrap:wrap;gap:14px;margin-top:34px}

/* ---------- buttons ---------- */
.btn{font-family:"IBM Plex Mono",monospace;font-size:.74rem;letter-spacing:.12em;
  text-transform:uppercase;padding:14px 22px;border:1px solid var(--indigo);
  cursor:pointer;transition:.18s;text-decoration:none;display:inline-block}
.btn.primary{background:var(--indigo);color:var(--paper)}
.btn.primary:hover{background:#22304a}
.btn.ghost{background:none;color:var(--indigo)}
.btn.ghost:hover{background:var(--indigo);color:var(--paper)}
.band .btn{border-color:var(--paper)}
.band .btn.primary{background:var(--paper);color:var(--ink)}
.band .btn.primary:hover{background:#F3F2EC}
.band .btn.ghost{color:var(--paper)}
.band .btn.ghost:hover{background:var(--paper);color:var(--ink)}

/* A two-colour keyboard ring stays visible on both the oat page and indigo
   bands. This is site-wide; hover treatments remain intentionally distinct. */
a:focus-visible,button:focus-visible{
  outline:2px solid var(--paper);outline-offset:2px;
  box-shadow:0 0 0 4px var(--madder);
}

/* ---------- sections ---------- */
.section{padding:60px 0;border-top:1px solid var(--ash)}
.section:first-of-type{border-top:0}
.klabel{font-family:"IBM Plex Mono",monospace;font-size:.7rem;letter-spacing:.2em;
  text-transform:uppercase;color:var(--madder);margin:0 0 18px}
h2{font-weight:400;font-size:clamp(1.7rem,3.4vw,2.5rem);line-height:1.1;
  letter-spacing:-.01em;margin:0 0 .4em}
h3{font-weight:500;font-size:1.12rem;margin:0 0 .3em}
h1,h2,h3{text-wrap:balance}
p{max-width:64ch;text-wrap:pretty}
.dim{color:var(--iron)}

/* ---------- make grid ---------- */
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  gap:1px;background:var(--ash);border:1px solid var(--ash);margin-top:8px}
.cell{background:var(--paper);padding:26px 24px;cursor:pointer;transition:.18s;
  min-height:150px;display:flex;flex-direction:column;justify-content:space-between}
.cell:hover{background:var(--paper-soft)}
.cell h3{margin:0}
.cell .num{font-family:"IBM Plex Mono",monospace;font-size:.68rem;color:var(--weld);
  letter-spacing:.14em}
.cell .desc{color:var(--iron);font-size:.95rem;margin:14px 0 0;max-width:none}
.cell .go{font-family:"IBM Plex Mono",monospace;font-size:.66rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--madder);margin-top:16px}

/* ---------- steps ---------- */
.steps{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:34px;margin-top:10px}
.step .n{font-family:"IBM Plex Mono",monospace;font-size:.78rem;color:var(--madder);
  letter-spacing:.14em;border-bottom:1px solid var(--ash);padding-bottom:10px;margin-bottom:14px}
.step p{color:var(--iron);font-size:.98rem}

/* ---------- feature band ---------- */
.band{background:var(--indigo);color:var(--paper)}
.band .wrap{padding:66px 28px}
.band h2{color:var(--paper)}
.band p{color:rgba(238,237,230,.82);max-width:56ch}
.band .klabel{color:var(--weld)}
.band .dim{color:rgba(238,237,230,.7)}

/* ---------- spec lists ---------- */
.specs{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
  gap:0;border-top:1px solid var(--ash);margin-top:26px}
.spec{padding:22px 0;border-bottom:1px solid var(--ash)}
.spec .t{font-family:"IBM Plex Mono",monospace;font-size:.7rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--iron);margin-bottom:8px}
.spec p{font-size:.98rem;max-width:38ch}

.two{display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:start}
.pad-top{margin-top:40px}

/* ---------- contact ---------- */
.cards{display:grid;grid-template-columns:1fr 1fr;gap:24px;margin-top:8px}
.card{border:1px solid var(--ash);padding:30px 28px;background:var(--paper)}
.card h3{font-weight:400;font-size:1.35rem}
.field{display:block;margin-top:16px}
.field label{font-family:"IBM Plex Mono",monospace;font-size:.66rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--iron);display:block;margin-bottom:6px}
.field input,.field textarea{width:100%;font-family:"Spectral",serif;font-size:1rem;
  color:var(--ink);background:var(--paper-soft);border:1px solid var(--ash);
  padding:11px 12px;border-radius:0}
.field textarea{min-height:88px;resize:vertical}
.field input:focus,.field textarea:focus{outline:2px solid var(--madder);outline-offset:1px}
.detail-list{list-style:none;padding:0;margin:26px 0 0;font-family:"IBM Plex Mono",monospace;
  font-size:.82rem;color:var(--iron);line-height:2}
.detail-list a{color:var(--madder);text-decoration:none}
.detail-list a:hover{text-decoration:underline}

/* ---------- image slots + composition rows ---------- */
.slot{position:relative;display:flex;align-items:flex-end;
  aspect-ratio:3/2;padding:16px;background:var(--paper-soft);
  border:1px solid var(--ash);margin-top:26px}
.slot--wide{aspect-ratio:16/9}
.slot--tall{aspect-ratio:4/5}
.slot img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.slot .brief{font-family:"IBM Plex Mono",monospace;font-size:.68rem;line-height:1.6;
  color:var(--iron);max-width:60ch}
.slot .brief b{display:block;font-weight:500;letter-spacing:.16em;text-transform:uppercase;
  color:var(--madder);margin-bottom:6px;font-size:.64rem}
.band .slot{background:rgba(238,237,230,.07);border-color:rgba(238,237,230,.3)}
.band .slot .brief{color:rgba(238,237,230,.72)}
.band .slot .brief b{color:var(--weld)}

.comp{display:grid;grid-template-columns:1fr;gap:20px;
  padding:34px 0;border-top:1px solid var(--ash)}
.comp:last-of-type{border-bottom:1px solid var(--ash)}
.comp .slot{margin-top:0}
.comp .n{font-size:.68rem;letter-spacing:.16em;color:var(--weld);margin-bottom:8px}
.comp h3{font-weight:500;font-size:1.12rem;margin:0 0 .4em}
.comp p{color:var(--iron);font-size:.98rem;max-width:44ch}
@media(min-width:760px){
  .comp{grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:40px;align-items:center}
}

/* fixed-setup note — the shooting constraint that holds across a set */
.setup{border-left:2px solid var(--weld);padding:2px 0 2px 16px;margin:26px 0 0;
  font-family:"IBM Plex Mono",monospace;font-size:.7rem;line-height:1.68;
  color:var(--iron);max-width:66ch}
.setup b{display:block;font-weight:500;letter-spacing:.16em;text-transform:uppercase;
  color:var(--madder);margin-bottom:6px;font-size:.64rem}
.band .setup{border-left-color:var(--weld);color:rgba(238,237,230,.72)}
.band .setup b{color:var(--weld)}

/* ---------- windows : the two doorways ---------- */
#windows{
  --wi-edge-gap:clamp(20px,4.6vw,68px);
  --wi-center-shift:clamp(9px,2vw,20px);
  --wi-normal-width:min(1024px,calc(100vw - var(--gap) - var(--dsel) - 56px));
  --wi-hero-width:min(1480px,max(var(--wi-normal-width),
    calc(100vw - var(--sel) - var(--dsel) - var(--wi-edge-gap) - var(--wi-edge-gap))));
}
#windows .big{font-family:"Spectral",serif;font-weight:400;
  font-size:clamp(1.12rem,1.9vw,1.34rem);line-height:1.62;max-width:60ch}
#windows .windows-hero-frame{
  width:var(--wi-hero-width);max-width:none;
  margin-left:50%;transform:translateX(calc(-50% - var(--wi-center-shift)));
  padding:0;border-style:solid;border-color:transparent;border-width:2px 2px 26px;
  border-image-source:url("a/hem-frame-indigo.62200af8.svg");
  border-image-slice:3 3 34 3;border-image-width:2px 2px 26px 2px;
  border-image-repeat:round;
}
#windows .routes{display:grid;grid-template-columns:minmax(0,1.85fr) minmax(0,1fr);
  gap:18px;height:clamp(400px,48vw,540px);margin-top:30px}
#windows .route{position:relative;display:block;overflow:hidden;border:0;border-radius:16px;
  min-height:0;background:var(--paper-soft);cursor:pointer;text-align:left;padding:0;
  font-family:inherit;color:var(--paper);text-decoration:none;
  box-shadow:inset 0 0 0 1px rgba(228,220,203,.42)}
#windows .route:hover{box-shadow:inset 0 0 0 1.5px rgba(228,220,203,.75)}
#windows .route .slot{position:absolute;inset:0;width:100%;height:100%;margin:0;
  border:0;background:var(--paper);aspect-ratio:auto}
#windows .route .body{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:16px 18px;
  display:block;background:linear-gradient(180deg,rgba(43,59,87,0) 0%,rgba(43,59,87,.78) 100%)}
#windows .route .k{display:block;font-family:"IBM Plex Mono",monospace;font-size:.62rem;
  letter-spacing:.2em;text-transform:uppercase;color:var(--paper-soft);opacity:.85;margin-bottom:4px}
#windows .route h3.t{display:block;font-family:"Fraunces",Georgia,serif;font-weight:400;
  font-size:1.15rem;letter-spacing:0;color:var(--paper);margin:0}
#windows .route:nth-child(1) img{object-position:center center}
#windows .route:nth-child(2) img{object-position:center 31%}
#windows .overlap{margin-top:22px;color:var(--iron);font-size:.92rem}
@media(max-width:720px){
  #windows .routes{grid-template-columns:1fr;height:auto;max-width:520px;margin-inline:auto}
  #windows .route:nth-child(1){aspect-ratio:5/4}
  #windows .route:nth-child(2){aspect-ratio:2/3}
}

/* ---------- blinds : the type list ---------- */
#blinds .blist{border-top:1px solid var(--ash);margin-top:26px}
/* ---------- blinds : the hero ----------
   Same device as the windows hero — the indigo hem frame, thin on three sides
   with the weighted hem along the bottom — and the same breakout, so the page
   opens wider than its own text column the way every other page hero does.
   Not the curtains treatment: that jali band is curtains' own artwork. */
#blinds{
  --bl-edge-gap:clamp(20px,4.6vw,68px);
  --bl-center-shift:clamp(9px,2vw,20px);
  --bl-normal-width:min(1024px,calc(100vw - var(--gap) - var(--dsel) - 56px));
  --bl-hero-width:min(1480px,max(var(--bl-normal-width),
    calc(100vw - var(--sel) - var(--dsel) - var(--bl-edge-gap) - var(--bl-edge-gap))));
}
#blinds .blinds-hero-frame{
  width:var(--bl-hero-width);max-width:none;
  margin-left:50%;transform:translateX(calc(-50% - var(--bl-center-shift)));
  padding:0;border-style:solid;border-color:transparent;border-width:2px 2px 26px;
  border-image-source:url("a/hem-frame-indigo.62200af8.svg");
  border-image-slice:3 3 34 3;border-image-width:2px 2px 26px 2px;
  border-image-repeat:round;
}

#blinds .btype{padding:28px 0;border-bottom:1px solid var(--ash);
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,275px);
  gap:30px;align-items:start}
#blinds .btype .slot{margin-top:0;aspect-ratio:1/1;padding:12px}
#blinds .btype h3{margin:0 0 4px}
#blinds .btype .mech{font-style:italic;color:var(--iron);font-size:1rem;margin-bottom:9px}
#blinds .btype p{margin:0;max-width:60ch}
#blinds .btype .opt{margin-top:9px;color:var(--iron);font-size:.96rem}
@media(max-width:760px){#blinds .btype{grid-template-columns:1fr;gap:18px}}

/* ---------- upholstery : the sets ---------- */
#upholstery .g8{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-top:26px}
#upholstery .g8 .slot{margin-top:0;aspect-ratio:4/3;padding:12px}
#upholstery .g3{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:26px}
#upholstery .g3 .slot{margin-top:0;aspect-ratio:4/5;padding:12px}
#upholstery .g5{display:grid;grid-template-columns:repeat(5,1fr);gap:12px;margin-top:26px}
#upholstery .g5 .slot{margin-top:0;aspect-ratio:3/4;padding:12px}
#upholstery .g4{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:26px}
#upholstery .g4 .slot{margin-top:0;aspect-ratio:3/2}
#upholstery .rel{display:flex;flex-direction:column}
#upholstery .relcap{font-family:"IBM Plex Mono",monospace;font-size:.7rem;
  letter-spacing:.1em;color:var(--iron);margin-top:10px}
@media(max-width:900px){
  #upholstery .g8{grid-template-columns:repeat(2,1fr)}
  #upholstery .g5{grid-template-columns:repeat(2,1fr)}
  #upholstery .g4{grid-template-columns:1fr}
}
@media(max-width:560px){#upholstery .g3{grid-template-columns:1fr}}

/* ---------- rugs : the sets ---------- */
#rugs .g2{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:26px}
#rugs .g2 .slot{margin-top:0;aspect-ratio:3/2}
#rugs .g4{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:26px}
#rugs .g4 .slot{margin-top:0;aspect-ratio:3/2}
#rugs .g3{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:26px}
#rugs .g3 .slot{margin-top:0;aspect-ratio:3/2;padding:12px}
#rugs .cap{font-family:"IBM Plex Mono",monospace;font-size:.7rem;letter-spacing:.1em;
  color:var(--iron);margin-top:10px}
#rugs .rel{display:flex;flex-direction:column}
@media(max-width:820px){
  #rugs .g2,#rugs .g4,#rugs .g3{grid-template-columns:1fr}
}

/* ---------- about ---------- */
#about .two{grid-template-columns:1.2fr .8fr;gap:56px;align-items:center}
#about .two > :only-child{grid-column:1/-1}
#about .two .slot{margin-top:0}
#about .g3{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:26px}
#about .g3 .slot{margin-top:0;aspect-ratio:4/5;padding:12px}
#about .specs{max-width:820px}
@media(max-width:820px){
  #about .two,#about .g3{grid-template-columns:1fr}
  #about .two{gap:8px}
}

/* ---------- rugs : two-section opening -----------------------------------
   One rectangular rug lies under the opening and Territory, end to end.
   It is faint where the page begins and gains opacity down to its far edge.
   Every value is a custom property, so the study page's tuning panel can move
   them live; the defaults here are what ships if the panel is removed.
   A soft paper veil sits behind each block of words so the copy stays
   readable where the rug is strongest, without turning into a card. */
body.rugs-featured #rugs .rug-field{
  --rug-from:0; --rug-to:.9; --rug-sat:.95;
  --rug-inset:clamp(10px,2.2vw,32px); --rug-gap:0px;
  --rug-veil:.62;
  position:relative;isolation:isolate;padding-bottom:var(--rug-gap);
}
body.rugs-featured #rugs .rug-field__rug{
  position:absolute;z-index:-2;top:0;bottom:var(--rug-gap);
  left:var(--rug-inset);right:var(--rug-inset);
  width:calc(100% - 2 * var(--rug-inset));height:calc(100% - var(--rug-gap));
  object-fit:cover;object-position:center center;display:block;
  filter:saturate(var(--rug-sat));
  -webkit-mask-image:linear-gradient(180deg,
    rgba(0,0,0,var(--rug-from)) 0%,
    rgba(0,0,0,calc(var(--rug-from) + (var(--rug-to) - var(--rug-from)) * .3)) 45%,
    rgba(0,0,0,var(--rug-to)) 100%);
  mask-image:linear-gradient(180deg,
    rgba(0,0,0,var(--rug-from)) 0%,
    rgba(0,0,0,calc(var(--rug-from) + (var(--rug-to) - var(--rug-from)) * .3)) 45%,
    rgba(0,0,0,var(--rug-to)) 100%);
}
body.rugs-featured #rugs .rug-open{padding:clamp(96px,13vh,150px) 0 clamp(110px,16vh,180px)}
body.rugs-featured #rugs .rug-territory{padding:0 0 clamp(120px,16vh,190px)}
body.rugs-featured #rugs .rug-copy{position:relative;max-width:62ch}
body.rugs-featured #rugs .rug-copy::before{
  content:"";position:absolute;z-index:-1;pointer-events:none;
  inset:-34px -44px;border-radius:40px;
  background:var(--paper);opacity:var(--rug-veil);filter:blur(22px);
}
body.rugs-featured #rugs .rug-territory h2{max-width:20ch}
@media(max-width:760px){
  body.rugs-featured #rugs .rug-field{--rug-inset:8px}
  body.rugs-featured #rugs .rug-open{padding:92px 0 120px}
  body.rugs-featured #rugs .rug-territory{padding:0 0 120px}
  body.rugs-featured #rugs .rug-copy::before{inset:-22px -18px;filter:blur(16px)}
}

/* study-page tuning panel (rugs-alt only) */
.rug-tune{position:fixed;left:14px;bottom:14px;z-index:60;
  font-family:"IBM Plex Mono",monospace;font-size:.72rem;color:var(--ink);
  background:var(--paper);border:1px solid var(--iron);border-radius:6px;
  box-shadow:0 6px 24px rgba(0,0,0,.18);max-width:min(300px,calc(100vw - 28px))}
.rug-tune>button{all:unset;cursor:pointer;display:block;padding:8px 12px;
  letter-spacing:.12em;text-transform:uppercase}
.rug-tune .rt-body{padding:0 12px 12px;display:grid;gap:8px}
.rug-tune[data-closed] .rt-body{display:none}
.rug-tune label{display:grid;gap:2px}
.rug-tune input[type=range],.rug-tune select{width:100%}
.rug-tune output{color:var(--iron)}
.rug-tune .rt-vals{font-size:.66rem;color:var(--iron);word-break:break-all;
  user-select:all;border-top:1px solid var(--paper-soft);padding-top:8px}

/* ---------- footer ---------- */
footer{background:var(--indigo);color:var(--paper);margin-top:0}
.foot{max-width:1080px;margin:0 auto;padding:54px 28px 40px;
  display:grid;grid-template-columns:minmax(220px,1.45fr) repeat(3,minmax(130px,1fr));
  gap:42px 34px;align-items:start}
.foot .mark{font-family:"Spectral",serif;font-weight:500;font-size:1.5rem;
  color:#F3F2EC;letter-spacing:.03em}
.foot .mark .amp{color:var(--weld);font-style:italic}
.foot-links{display:block}
.foot-head{font-family:"IBM Plex Mono",monospace;font-size:.65rem;letter-spacing:.16em;
  text-transform:uppercase;color:rgba(238,237,230,.5);margin:2px 0 16px}
.foot-links a{font-family:"IBM Plex Mono",monospace;font-size:.7rem;letter-spacing:.13em;
  text-transform:uppercase;background:none;border:0;color:rgba(238,237,230,.8);
  cursor:pointer;text-decoration:none;display:block;margin:.6em 0}
.foot-links a:hover{color:var(--paper)}
.foot .col p{color:rgba(238,237,230,.72);font-size:.9rem;max-width:30ch;margin:.4em 0 0}
.foot-legal{grid-column:1/-1;display:block;border-top:1px solid rgba(238,237,230,.18);
  padding-top:20px;color:rgba(238,237,230,.5);font-family:"IBM Plex Mono",monospace;
  font-size:.65rem;letter-spacing:.08em}
@media(max-width:760px){
  .foot{grid-template-columns:1fr 1fr}
  .foot .col,.foot-legal{grid-column:1/-1}
}
@media(max-width:460px){
  .foot{grid-template-columns:1fr;gap:30px}
  .foot .col,.foot-legal{grid-column:auto}
}

@media(max-width:1000px){
  .panel{display:none !important}
  .mobonly{display:inline-block}
  .navtree{display:flex;flex-wrap:wrap;gap:6px;padding-bottom:0;margin-bottom:0}
  .navtree .navitem{margin:0}
  .nav-link{font-size:.7rem;padding:8px 11px;letter-spacing:.1em}
  nav{gap:6px}
  .bar{gap:14px;flex-wrap:nowrap;border-radius:17px;padding:13px 16px}
  .decideband span{letter-spacing:.16em;font-size:.72rem}
  .decideband{padding:24px 11px}
}
@media(max-width:720px){
  .two,.cards{grid-template-columns:1fr}
  .hero-inner{padding:64px 24px 56px}
}
@media(prefers-reduced-motion:reduce){*{animation:none!important;scroll-behavior:auto}}

/* ---------- curtains : jali hero, the four-room grid, the making pair ---------- */
#curtains{
  --cu-edge-gap:clamp(20px,4.6vw,68px);
  --cu-center-shift:clamp(9px,2vw,20px);
  --cu-normal-width:min(1024px,calc(100vw - var(--gap) - var(--dsel) - 56px));
  --cu-hero-width:min(1480px,max(var(--cu-normal-width),
    calc(100vw - var(--sel) - var(--dsel) - var(--cu-edge-gap) - var(--cu-edge-gap))));
  /* halfway between the hero and the text column */
  --cu-look-width:calc(var(--cu-hero-width) / 2 + var(--cu-normal-width) / 2);
}

/* ── hero: copy and a portrait moving room study ────────────────────────── */
#curtains .cu-intro{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(340px,.95fr);
  gap:clamp(30px,4vw,52px);align-items:center;
}
#curtains .cu-intro-copy h1{font-weight:300;font-size:clamp(2.2rem,5vw,3.4rem);
  line-height:1.06;margin:.35em 0 .3em}
#curtains .cu-intro-copy .dim{font-size:1.1rem;max-width:60ch}
#curtains .cu-hero{
  position:relative;width:120%;max-width:none;justify-self:start;align-self:start;
  aspect-ratio:560/704;overflow:hidden;
  background:var(--ash);padding:0;border-style:solid;border-color:transparent;
  border-width:2px 2px 26px;
  border-image-source:url("a/hem-frame-indigo.62200af8.svg");
  border-image-slice:3 3 34 3;border-image-width:2px 2px 26px 2px;
  border-image-repeat:round;
  box-sizing:border-box;
}
#curtains .cu-hero video{
  width:100%;height:100%;object-fit:cover;display:block;background:var(--ash);
}
@media(max-width:760px){
  #curtains .cu-intro{grid-template-columns:1fr}
  #curtains .cu-hero{width:min(100%,520px);margin-inline:auto}
}

/* ── the look is yours ────────────────────────────────────────────────────
   Four rooms at full strength; the words sit on a solid paper plate laid
   over the centre, so each quadrant keeps its outer half. Nothing is faded
   and nothing is read through anything. ------------------------------------ */
#curtains .look{
  position:relative;isolation:isolate;overflow:hidden;
  width:var(--cu-look-width);max-width:none;
  margin:8px 0 0 50%;
  transform:translateX(calc(-50% - var(--cu-center-shift)));
  border-radius:18px;aspect-ratio:3/2;
  display:flex;align-items:center;justify-content:center;
  padding:clamp(24px,4vw,56px);
}
#curtains .look-grid{
  position:absolute;inset:0;z-index:0;
  display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr;gap:0;
}
#curtains .look-grid img{width:100%;height:100%;object-fit:cover;display:block}

#curtains .look-card{
  position:relative;z-index:3;
  width:min(46%,46ch);
  /* --ash: the palette's card ground. Clearly deeper than the page, and
     still 8.2:1 against --ink. Body copy in here must stay --ink, not --iron. */
  background:var(--ash);
  padding:clamp(22px,2.4vw,34px) clamp(22px,2.4vw,34px) clamp(24px,2.6vw,36px);
  border-radius:10px;
  box-shadow:0 2px 26px rgba(42,38,32,.18), inset 0 0 0 1px rgba(43,59,87,.22);
}
#curtains .look-card h2{margin-top:.12em}
#curtains .look-card p{color:var(--ink)}
#curtains .look-frame{
  position:absolute;inset:0;z-index:4;pointer-events:none;
  border:2px solid var(--indigo);border-radius:18px;
}
/* which quadrant is which — a swatch tag, legible on pale cloth or dark */
#curtains .look-tags{position:absolute;inset:0;z-index:2;pointer-events:none}
#curtains .look-tags span{
  position:absolute;font-family:"IBM Plex Mono",monospace;font-size:.6rem;
  letter-spacing:.18em;text-transform:uppercase;color:var(--indigo);
  background:rgba(228,220,203,.93);padding:4px 8px;border-radius:3px;
}
#curtains .look-tags span:nth-child(1){top:14px;left:16px}
#curtains .look-tags span:nth-child(2){top:14px;right:16px}
#curtains .look-tags span:nth-child(3){bottom:14px;left:16px}
#curtains .look-tags span:nth-child(4){bottom:14px;right:16px}
@media(max-width:720px){
  #curtains .look{aspect-ratio:auto;padding:18px}
  #curtains .look-card{width:100%}
  #curtains .look-tags{display:none}
}

/* ── what's possible: selvedge frame, standard column width ──────────────── */
#curtains .wp-frame{
  padding:0;border:14px solid transparent;
  border-image-source:url("a/selvedge-frame.d79da8b3.svg");
  border-image-slice:32;border-image-width:14px;border-image-repeat:round;
}
#curtains .possibility-images{
  display:grid;grid-template-columns:minmax(0,2fr) minmax(220px,.72fr);
  gap:18px;align-items:stretch;margin-top:26px;
}
#curtains .possibility-images .wp-frame{margin-top:0}
#curtains .material-study{display:flex;flex-direction:column;margin:0;min-width:0}
#curtains .material-study .frame{display:block;position:relative;flex:1;overflow:hidden;
  min-height:0;border:1px solid var(--ash)}
#curtains .material-study .frame.wp-frame{
  border:14px solid transparent;border-image-source:url("a/selvedge-frame.d79da8b3.svg");
  border-image-slice:32;border-image-width:14px;border-image-repeat:round;
}
#curtains .material-study img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:center 47%;display:block}
#curtains .material-study figcaption,#curtains .room-scale figcaption{
  font-family:"IBM Plex Mono",monospace;font-size:.64rem;line-height:1.55;
  letter-spacing:.03em;color:var(--iron)}
#curtains .material-study figcaption{margin-top:9px}
#curtains .room-scale{position:relative;margin:0;overflow:hidden;background:var(--paper-soft)}
#curtains .room-scale img{display:block;width:100%;height:clamp(310px,42vw,570px);
  object-fit:cover;object-position:center 52%}
#curtains .room-scale figcaption{position:absolute;left:max(22px,var(--gap));bottom:20px;
  max-width:48ch;margin:0;padding:10px 12px;color:var(--paper);
  background:rgba(31,42,63,.84)}
@media(max-width:720px){
  #curtains .possibility-images{grid-template-columns:1fr}
  #curtains .material-study .frame{aspect-ratio:4/5}
  #curtains .room-scale figcaption{left:20px;right:max(20px,var(--dsel));bottom:16px}
}

/* ── on making ────────────────────────────────────────────────────────────
   Copy top-left, one study bottom-right of it, the second below-left, the
   two frames touching at a single corner. Gaps are zero at the meeting
   point; the air comes from padding on the copy instead. ------------------- */
#curtains .making{
  --mk:clamp(185px,25.3vw,315px);
  display:grid;grid-template-columns:1fr var(--mk);gap:0;
  margin-top:4px;
}
#curtains .making-copy{
  grid-column:1;grid-row:1;align-self:start;
  padding-right:clamp(20px,4vw,58px);padding-bottom:clamp(26px,3.4vw,46px);
}
#curtains .making-copy .klabel{margin-top:0}
#curtains .making figure{margin:0}
#curtains .making-a{grid-column:2;grid-row:1;align-self:end;width:var(--mk)}
/* fills the text column, so its left edge is the paragraph's left edge and
   its top-right corner lands on the study above */
#curtains .making-b{grid-column:1;grid-row:2;align-self:start;width:100%}
#curtains .making .frame{
  display:block;padding:0;border:11px solid transparent;
  border-image-source:url("a/tenter-frame-madder.766d9f60.svg");
  border-image-slice:24;border-image-width:11px;border-image-repeat:round;
}
#curtains .making img{display:block;width:100%;height:auto;object-fit:cover}
#curtains .making-a img{aspect-ratio:4/5}
#curtains .making-b img{aspect-ratio:1500/1076}
#curtains .making figcaption{
  font-family:"IBM Plex Mono",monospace;font-size:.64rem;line-height:1.6;
  letter-spacing:.04em;color:rgba(238,237,230,.7);
}
#curtains .making-a figcaption{margin-bottom:9px}   /* above, so the corner meets */
#curtains .making-b figcaption{margin-top:9px}
@media(max-width:700px){
  #curtains .making{grid-template-columns:1fr;--mk:min(286px,68vw)}
  #curtains .making-copy{grid-column:1;grid-row:1;padding:0 0 22px}
  #curtains .making-a{grid-column:1;grid-row:2;justify-self:start;margin-bottom:22px}
  #curtains .making-b{grid-column:1;grid-row:3}
}


/* ═══ added by build-site.py — real pages, real images ═══ */
.slot.filled{background:none;border:0;padding:0}
.slot.filled img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.slot.filled video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.slot.native{aspect-ratio:auto;display:block}
.slot.native img,.slot.native video{position:static;width:100%;height:auto}

figure.shot{margin:26px 0 0}
figure.shot .frame{display:block;border:1px solid var(--ash)}
figure.shot img{display:block;width:100%;height:auto}
figure.shot figcaption{font-family:"IBM Plex Mono",monospace;font-size:.68rem;
  letter-spacing:.1em;color:var(--iron);margin-top:9px}
.band figure.shot .frame{border-color:rgba(238,237,230,.3)}
.band figure.shot figcaption{color:rgba(238,237,230,.72)}
.g2x{display:grid;grid-template-columns:1fr 1fr;gap:18px;align-items:start}
.g2x figure.shot{margin-top:26px}
@media(max-width:720px){.g2x{grid-template-columns:1fr}}

/* One visual object made from the owner's own texture photographs. */
figure.material-study{margin:30px 0 0}
.material-scroll{overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none}
.material-scroll::-webkit-scrollbar{display:none}
.material-strip{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:1px;
  min-width:760px;background:var(--ash);border:1px solid var(--ash)}
.material-strip img{display:block;width:100%;height:auto;aspect-ratio:1;object-fit:cover}
.material-study figcaption{font-family:"IBM Plex Mono",monospace;font-size:.68rem;
  letter-spacing:.1em;color:var(--iron);margin-top:9px}

/* The recorded cushions setting uses two upright cloth studies as one unit. */
.cushion-range-pair{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.cushion-range-pair img{display:block;width:100%;height:auto}

/* nav as real links */
nav a.nav-link{text-decoration:none}
@media(max-width:1000px){
  .bar{flex-direction:column;align-items:stretch;gap:5px}
  nav{width:100%;overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none}
  nav::-webkit-scrollbar{display:none}
  .navgroup,nav>.nav-link{flex:0 0 auto}
}
#windows a.route{text-decoration:none;color:inherit;display:block}
#windows a.route .slot{display:block;position:absolute}
.drop a{text-decoration:none}
.foot-links a{display:block;background:none;border:0;padding:0;text-align:left;
  color:rgba(238,237,230,.72);font-family:"IBM Plex Mono",monospace;font-size:.7rem;
  letter-spacing:.1em;text-transform:uppercase;cursor:pointer;text-decoration:none;margin:.6em 0}
.foot-links a:hover{color:#EEEDE6}
.skip{position:absolute;left:-9999px}
.skip:focus{left:8px;top:8px;z-index:100;background:var(--paper);
  padding:10px 14px;border:1px solid var(--madder)}

/* ═══ W01 window band — six-facade strip in a full-bleed colour frame ═══
   An end-to-end colour field that runs UNDER the fixed selvedge (left) and the
   decide bar (right): it's static content, so z-index 60 on those keeps them on
   top. The strip sits inside with an equal band of colour above and below it —
   that symmetric margin is the frame. --w01frame sets that distance. */
.w01band{
  --w01frame:clamp(14px,2.2vw,26px);        /* equal colour above & below the strip */
  background:var(--madder-d);                /* fresh accent; not the indigo used elsewhere */
  margin-top:clamp(10px,2vw,22px);           /* breakout comes from .bleed .bleed-flush */
  margin-bottom:clamp(10px,2vw,22px);
  padding:var(--w01frame) 0;
}
.w01band .w01{width:100%;max-width:none;height:auto;margin:0 auto}
.w01{position:relative;overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none}
.w01::-webkit-scrollbar{display:none}
.w01 img{display:block;width:1440px;max-width:none;height:auto}
@media(min-width:900px){
  .w01{overflow:hidden}
  .w01 img{width:100%;height:auto}
}

/* ═══ home — mosaic hero ═══
   A single pre-composed wall of real photographs. Desktop and mobile each use
   one responsive image request instead of constructing 105/54 separate tiles.
   Full-bleed like the W01 band above: margins cancel the body's own left/right
   inset so the mosaic reaches the true viewport edge and runs UNDER the fixed
   selvedge and decide tab (both z-index:60; this sits below that, unset). */
#home .gridhero{position:relative;overflow:hidden;background:var(--paper);
  margin-top:clamp(10px,2vw,22px)}      /* breakout comes from .bleed .bleed-flush */
#home .gridhero-picture,#home .gridhero-mosaic{display:block;width:100%}
#home .gridhero-mosaic{height:auto;filter:saturate(.62) brightness(.96)}
#home .gridhero-scrim{position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(31,42,63,.24) 0%,rgba(31,42,63,.24) 42.86%,
    rgba(31,42,63,.93) 57.14%,rgba(31,42,63,.93) 100%)}
@media(max-width:700px){#home .gridhero-scrim{
  background:linear-gradient(180deg,rgba(31,42,63,.24) 0%,rgba(31,42,63,.24) 44.44%,
    rgba(31,42,63,.93) 55.56%,rgba(31,42,63,.93) 100%)}}
/* The grid hero is full-bleed, so its overlaid text sits under the fixed
   selvedge (--sel) and the utility tabs (--dsel) unless it is padded away from
   both. --dsel is the wider of the two, so using it on both sides clears each
   fixture and keeps the block optically centred. */
#home .gridhero-text{position:absolute;left:0;right:0;bottom:0;display:flex;align-items:flex-end;
  justify-content:center;padding:0 max(20px,var(--dsel)) 26px;text-align:center}
#home .gridhero-text .inner{max-width:640px}
#home .gridhero-text .eyebrow{color:var(--paper-soft);opacity:.85;margin-bottom:12px;
  text-transform:none}
#home .gridhero-text h1{font-weight:400;font-size:clamp(28px,4.4vw,46px);
  margin:0 0 14px;color:var(--paper);line-height:1.05}
#home .gridhero-text .sub{max-width:52ch;margin:0 auto;color:var(--paper-soft);
  font-size:clamp(14px,1.3vw,17px);line-height:1.6}
#home .gridhero-ctas{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;
  padding:14px 20px 8px}
#home .gridhero-actions{padding-top:30px}

/* ═══ home — bento routes ═══
   Windows keeps the tall box on purpose: a curtain or blind needs its vertical
   drop to read, and a square crop would cut the thing that matters. The other
   three sit in the remaining space at whatever shape suits a room photo.
   Rounded corners, and the frame is a translucent ring sitting just inside the
   edge rather than an opaque border, so it reads as glass over the photo. */
#home .bento{display:grid;grid-template-columns:1.04fr .96fr .8fr;
  grid-template-rows:1fr 1fr;gap:14px;margin-top:14px;height:clamp(520px,56vw,650px)}
#home .bento a{position:relative;display:block;overflow:hidden;text-decoration:none;
  background:var(--paper-soft);border-radius:16px;
  box-shadow:inset 0 0 0 1px rgba(228,220,203,.4)}
#home .bento a img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
#home .bento a:hover{box-shadow:inset 0 0 0 1.5px rgba(228,220,203,.75)}
#home .bento .b-windows{grid-column:1/2;grid-row:1/3}
#home .bento .b-furniture{grid-column:2/3;grid-row:1/3}
#home .bento .b-furniture img{object-position:center 54%}
#home .bento .b-floors{grid-column:3/4;grid-row:1/2}
#home .bento .b-finish{grid-column:3/4;grid-row:2/3}
#home .bento .label{position:absolute;left:0;right:0;bottom:0;padding:16px 18px;
  background:linear-gradient(180deg,rgba(43,59,87,0) 0%,rgba(43,59,87,.78) 100%)}
#home .bento .k{display:block;font-family:"IBM Plex Mono",monospace;font-size:.62rem;
  letter-spacing:.2em;text-transform:uppercase;color:var(--paper-soft);opacity:.85;margin-bottom:4px}
#home .bento .t{display:block;font-family:"Fraunces",Georgia,serif;font-weight:400;
  font-size:1.15rem;color:var(--paper)}
@media(max-width:900px){#home .bento{grid-template-columns:1fr 1fr;grid-template-rows:auto;height:auto}
  #home .bento .b-windows{grid-column:1/2;grid-row:1/2;aspect-ratio:4/5}
  #home .bento .b-furniture{grid-column:2/3;grid-row:1/2;aspect-ratio:4/5}
  #home .bento .b-floors{grid-column:1/2;grid-row:2/3;aspect-ratio:1/1}
  #home .bento .b-finish{grid-column:2/3;grid-row:2/3;aspect-ratio:1/1}}

/* ═══ blinds — a hairline on each type photo ═══
   These were carrying the full woven-tick selvedge at 14px, which is a lot of
   frame around a 275px picture and left the photograph looking inset. The
   photographs are the point here, so the edge is now a single indigo rule and
   the picture is bigger. */
#blinds .btype .slot.filled{
  padding:0;border:1px solid var(--indigo);border-image:none;
}

/* ═══ cushions — three frames for three kinds of image ═══
   Hero: the same madder Hem band as upholstery's hero, in madder deep.
   "Where the cloth comes from": madder deep selvedge, closed rectangle.
   The five compositions: indigo tenter — a hairline with pin marks and
   open corners, lighter than the other two since there are five of them
   sitting together. */
#cushions{
  --cu-edge-gap:clamp(20px,4.6vw,68px);
  --cu-center-shift:clamp(9px,2vw,20px);
  --cu-normal-width:min(1024px,calc(100vw - var(--gap) - var(--dsel) - 56px));
  --cu-hero-width:min(1480px,max(var(--cu-normal-width),
    calc(100vw - var(--sel) - var(--dsel) - var(--cu-edge-gap) - var(--cu-edge-gap))));
}
#cushions .slot--wide.filled:not(.native){
  width:var(--cu-hero-width);max-width:none;
  margin:0 0 0 50%;
  transform:translateX(calc(-50% - var(--cu-center-shift)));
  padding:0;border-style:solid;border-color:transparent;
  border-width:2px 2px 26px;
  border-image-source:url("a/hem-frame.0ebc2d86.svg");
  border-image-slice:3 3 34 3;
  border-image-width:2px 2px 26px 2px;
  border-image-repeat:round;
}
#cushions .cushion-ranges{
  padding:0;border:14px solid transparent;
  border-image-source:url("a/selvedge-frame-madder.535fbb17.svg");
  border-image-slice:32;
  border-image-width:14px;
  border-image-repeat:round;
}
#cushions .comp .slot.filled{
  padding:0;border:11px solid transparent;
  border-image-source:url("a/tenter-frame-indigo.8b50236d.svg");
  border-image-slice:24;
  border-image-width:11px;
  border-image-repeat:round;
}

/* ═══ upholstery — framed image compositions ═══ */
#upholstery{
  --up-edge-gap:clamp(20px,4.6vw,68px);
  --up-center-shift:clamp(9px,2vw,20px);
  --up-normal-width:min(1024px,calc(100vw - var(--gap) - var(--dsel) - 56px));
  --up-hero-width:min(1480px,max(var(--up-normal-width),
    calc(100vw - var(--sel) - var(--dsel) - var(--up-edge-gap) - var(--up-edge-gap))));
  --up-window-width:calc(var(--up-hero-width) / 2 + var(--up-normal-width) / 2);
}

#upholstery .upholstery-hero-frame{
  width:var(--up-hero-width);max-width:none;
  margin:0 0 0 50%;
  transform:translateX(calc(-50% - var(--up-center-shift)));
  border-style:solid;border-color:transparent;
  border-width:2px 2px 26px;
  border-image-source:url("a/hem-frame.0ebc2d86.svg");
  border-image-slice:3 3 34 3;
  border-image-repeat:round;
  border-image-width:2px 2px 26px 2px;
}
#upholstery .upholstery-intro-copy{margin:0 0 clamp(38px,5vw,64px)}
#upholstery .upholstery-intro-copy h1{
  max-width:19ch;font-weight:300;font-size:clamp(2.2rem,5vw,3.4rem);
  line-height:1.06;margin:.35em 0 .3em;
}
#upholstery .upholstery-intro-copy .lede{max-width:56ch;margin:18px 0 0}

#upholstery .upholstery-cloth-window{
  position:relative;
  width:var(--up-window-width);max-width:none;
  margin:0 0 0 50%;
  transform:translateX(calc(-50% - var(--up-center-shift)));
  padding:clamp(8px,1vw,13px) clamp(8px,1vw,13px) clamp(18px,1.7vw,25px);
  background:var(--indigo);
  box-shadow:inset 1px 1px 0 rgba(228,220,203,.28),
    inset -2px -2px 0 rgba(20,29,45,.38);
}
#upholstery .upholstery-cloth-window::after{
  content:"";position:absolute;left:clamp(8px,1vw,13px);right:clamp(8px,1vw,13px);
  bottom:clamp(6px,.55vw,8px);height:3px;opacity:.62;
  background:repeating-linear-gradient(90deg,var(--paper) 0 2px,transparent 2px 10px);
}
#upholstery .upholstery-cloth-window__copy{
  display:grid;grid-template-columns:minmax(0,1.18fr) minmax(240px,.82fr);
  column-gap:clamp(28px,5vw,68px);align-items:end;
  min-height:clamp(190px,19vw,275px);
  padding:clamp(26px,4.2vw,58px);
  background:var(--paper);
  border-bottom:clamp(10px,1.15vw,16px) solid var(--indigo);
}
#upholstery .upholstery-cloth-window__copy .klabel{grid-column:1/-1;align-self:start}
#upholstery .upholstery-cloth-window__copy h2{margin-bottom:0;max-width:18ch}
#upholstery .upholstery-cloth-window__copy p{
  align-self:start;margin:0;max-width:42ch;padding-top:.2em;
}
#upholstery .g8.upholstery-cloth-window__panes{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(5px,.65vw,9px);margin:0;background:var(--indigo);
}
#upholstery .g8.upholstery-cloth-window__panes .slot{
  margin:0;padding:0;aspect-ratio:4/3;border:0;
}

#upholstery .g5{grid-template-columns:1fr;width:min(380px,100%)}
#upholstery .g5 .upholstery-recovery-frame{
  padding:0;border:14px solid transparent;
  border-image-source:url("a/selvedge-frame.d79da8b3.svg");
  border-image-slice:32;
  border-image-width:14px;
  border-image-repeat:round;
}

@media(max-width:720px){
  #upholstery .upholstery-cloth-window__copy{grid-template-columns:1fr;min-height:0}
  #upholstery .upholstery-cloth-window__copy .klabel{grid-column:auto}
  #upholstery .upholstery-cloth-window__copy h2{margin-bottom:.4em}
}
@media(max-width:560px){
  #upholstery .g8.upholstery-cloth-window__panes{grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* ── enquiry form ─────────────────────────────────────────────────────────
   Built to FORM-SPEC.md. Chips are real radios and checkboxes with the input
   visually hidden, so keyboard and screen-reader behaviour is the browser's
   rather than ours. */
/* .field sets display:block, which outranks the browser's own [hidden] rule.
   Without this, hiding a field does nothing at all. */
.enq [hidden], .enq-done[hidden]{display:none !important}
.enq{max-width:680px;margin-top:8px}
.enq .step{border:0;padding:0;margin:0 0 38px}
.enq fieldset.step{min-width:0}
.enq .q{font-family:"IBM Plex Mono",monospace;font-size:.78rem;letter-spacing:.1em;
        text-transform:uppercase;color:var(--ink);margin:0 0 12px;padding:0;
        display:flex;gap:12px;align-items:baseline;line-height:1.5}
.enq .q-n{color:var(--madder);font-size:.7rem}
.enq .sub-q{text-transform:none;letter-spacing:.02em;font-family:"Spectral",serif;
            font-size:1.02rem;color:var(--iron)}
.enq .q-note{font-size:.92rem;color:var(--iron);margin:-4px 0 14px;max-width:56ch}
.enq .q-note.q-note-after{margin-top:18px}
.enq .step.sub{margin-top:-10px;padding:24px 26px 26px;border-left:2px solid var(--madder);
                background:var(--paper-soft)}
.enq .step.sub .sub-q{margin-bottom:18px;color:var(--ink)}
.enq .prompt{margin-top:30px;max-width:58ch}
.prompts-intro{font-size:.94rem;color:var(--iron);max-width:52ch;margin:.6em 0 30px}
.enq .prompt label{display:block;font-family:"Spectral",serif;font-size:1.03rem;
                   letter-spacing:0;text-transform:none;color:var(--ink);
                   font-style:italic;margin:0 0 2px;opacity:.85}
.enq .prompt input{background:transparent;border:0;border-bottom:1px solid var(--ash);
                   padding:6px 0;font-size:1.05rem}
.enq .prompt input:focus{outline:none;border-bottom-color:var(--madder);
                         box-shadow:0 1px 0 0 var(--madder)}
.enq .aside{font-size:.88rem;color:var(--iron);margin-top:14px}
.enq .aside a{color:var(--madder)}

.chips{display:flex;flex-wrap:wrap;gap:8px}
.chip{position:relative;display:inline-flex}
.chip input{position:absolute;opacity:0;width:100%;height:100%;margin:0;cursor:pointer}
.chip span{display:inline-block;padding:9px 15px;border:1px solid var(--ash);
           background:var(--paper);font-size:.95rem;line-height:1.3;
           transition:background .12s,border-color .12s,color .12s}
.chip input:checked+span{background:var(--indigo);border-color:var(--indigo);color:var(--paper)}
.chip input:focus-visible+span{outline:2px solid var(--madder);outline-offset:2px}
@media (hover:hover){.chip input:not(:checked):hover+span{border-color:var(--iron)}}

.enq .field label{display:flex;justify-content:space-between;gap:14px;align-items:baseline}
.enq .hint{font-family:"Spectral",serif;font-size:.82rem;letter-spacing:0;
           text-transform:none;color:var(--iron);font-weight:400}
.enq .err{display:block;font-family:"IBM Plex Mono",monospace;font-size:.72rem;
          letter-spacing:.06em;color:var(--madder-d);margin-top:8px}
.enq .form-err{margin-top:14px}
.enq .field.bad input,.enq .field.bad textarea{border-color:var(--madder-d)}
.enq .step.bad .chip span{border-color:var(--madder-d)}

.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

.enq-foot{border-top:1px solid var(--ash);padding-top:24px;margin-top:8px}
.enq .fineprint{font-size:.86rem;color:var(--iron);max-width:60ch;margin:0 0 20px}
.enq .fineprint a{color:var(--madder)}

.enq-done{max-width:640px}
.enq-done h2{margin-top:0}
.enq-done p{margin:0 0 .9em}
.enq-done .next{font-size:1.05rem}
.enq-done .quiet{font-size:.94rem;color:var(--iron)}
.enq-done a{color:var(--madder)}
.enq-done:focus{outline:none}

@media (max-width:560px){
  .enq .step{margin-bottom:32px}
  .chip span{padding:11px 14px}
  .enq .step.sub{padding-left:12px}
}

/* ── stages ───────────────────────────────────────────────────────────────
   Three named parts instead of nine numbers. The whole form is in the HTML;
   the script collapses it, so without JavaScript this is one long page that
   still works. */
.stages{display:flex;flex-wrap:wrap;gap:6px;list-style:none;padding:0;
        margin:0 0 40px;font-family:"IBM Plex Mono",monospace;font-size:.72rem;
        letter-spacing:.1em;text-transform:uppercase}
.stages[hidden]{display:none}
.stages>li{display:flex}
.stage-tab{display:flex;align-items:baseline;gap:9px;padding:10px 18px;
           color:var(--iron);border-radius:2px;
           background:none;border:0;font:inherit;letter-spacing:inherit;
           text-transform:inherit;text-align:left;
           cursor:pointer;-webkit-user-select:none;user-select:none;
           transition:background .18s ease,color .18s ease}
/* hovering shows the same soft ground the current stage sits on */
.stage-tab:hover{background:var(--paper-soft);color:var(--ink)}
.stage-tab:focus-visible{outline:none;background:var(--paper-soft);color:var(--ink);
           box-shadow:inset 0 0 0 1.5px var(--indigo)}
.stage-tab .stage-n{color:var(--madder)}
.stage-tab.current{background:var(--paper-soft);color:var(--ink)}
.stage-tab.done{color:var(--ink)}
.stage-tab.done .stage-n::after{content:" ·"}

.stage{border:0;padding:0;margin:0}
.stage-nav{display:flex;flex-wrap:wrap;align-items:center;gap:14px;margin-top:34px}
.mins{font-family:"IBM Plex Mono",monospace;font-size:.7rem;letter-spacing:.12em;
      text-transform:uppercase;color:var(--iron);margin-left:auto}

/* ── stacked choices with an explanation each ─────────────────────────── */
.opts{display:block;border-top:1px solid var(--ash)}
.opt{position:relative;display:flex;gap:14px;align-items:flex-start;
     padding:16px 4px;border-bottom:1px solid var(--ash);cursor:pointer}
.opt input{position:absolute;opacity:0;width:100%;height:100%;left:0;top:0;margin:0;cursor:pointer}
.opt-mark{flex:0 0 auto;width:15px;height:15px;margin-top:5px;border-radius:50%;
          border:1px solid var(--ash);background:var(--paper);transition:border-color .12s}
.opt input:checked ~ .opt-mark{border:5px solid var(--indigo);background:var(--paper)}
.opt input:focus-visible ~ .opt-mark{outline:2px solid var(--madder);outline-offset:2px}
.opt-body{display:block}
.opt-title{display:block;font-size:1.05rem;line-height:1.35}
.opt-desc{display:block;font-size:.92rem;color:var(--iron);margin-top:3px}
@media (hover:hover){.opt:hover .opt-mark{border-color:var(--iron)}}

/* ── the contact page: a way in, not a wall of questions ───────────────── */
.begin{display:grid;grid-template-columns:1fr minmax(260px,340px);gap:48px;align-items:start}
.begin-card{background:var(--indigo);color:var(--paper);padding:30px 30px 34px}
.begin-card .klabel{color:var(--paper);opacity:.72;margin-bottom:22px}
.begin-card dl{margin:0}
.begin-card dt{font-family:"IBM Plex Mono",monospace;font-size:.66rem;letter-spacing:.14em;
               text-transform:uppercase;opacity:.66;margin-top:18px}
.begin-card dd{margin:4px 0 0;padding-bottom:14px;border-bottom:1px solid rgba(228,220,203,.22);
               font-size:1.02rem;overflow-wrap:anywhere}
.begin-card dd a{color:var(--paper);text-decoration:none;border-bottom:1px solid rgba(228,220,203,.4)}
.begin-card dd a:hover{border-bottom-color:var(--paper)}
.begin-card p{font-size:.9rem;opacity:.75;margin:22px 0 0;max-width:30ch}

.begin-ways{display:grid;grid-template-columns:repeat(3,1fr);gap:0;
            border-top:1px solid var(--ash)}
.way{display:block;padding:30px 26px 34px;border-right:1px solid var(--ash);
     text-decoration:none;color:inherit;transition:background .14s}
.way:last-child{border-right:0}
.way:hover{background:var(--paper-soft)}
.way-n{font-family:"IBM Plex Mono",monospace;font-size:.7rem;letter-spacing:.14em;color:var(--madder)}
.way h3{margin:.5em 0 .35em;font-weight:400;font-size:1.4rem}
.way p{font-size:.95rem;color:var(--iron);margin:0}

@media (max-width:820px){
  .begin{grid-template-columns:1fr;gap:32px}
  .begin-ways{grid-template-columns:1fr}
  .way{border-right:0;border-bottom:1px solid var(--ash);padding:24px 0 26px}
  .way:last-child{border-bottom:0}
}
@media (max-width:560px){
  .stages{font-size:.66rem;gap:4px}
  .stage-tab{padding:8px 12px}
  .mins{margin-left:0;width:100%}
}

/* ── lines: three weights, not one ────────────────────────────────────────
   Every rule on the site used to be 1px of --ash, which is 1.35:1 against the
   paper. A page division and a row separator inside a list were drawn
   identically, so the lines carried no meaning, and the ones that stopped at
   the text column read as failing to reach rather than as a decision.

   Three tiers now, and the difference is legible:

     --rule  page divisions. Full width, and deliberately fading out to the
             right, so a line that does not reach the edge is doing it on
             purpose. Echoes the selvedge, which is where the eye starts.
     --ash   content rules inside a section. The quietest — unchanged.
     --edge  controls. Inputs, chips, the radio marks. Not decoration: this
             border is the only thing saying "you can type here", so it clears
             3:1 while the decorative rules stay soft. */
:root{
  --rule:#B3A88E;   /* 1.73:1 — a division you notice without reading it */
  --edge:#8A7E66;   /* 2.93:1 — an affordance you must be able to see */
}

.section{
  border-top:0;
  background-image:linear-gradient(90deg,var(--rule) 0%,var(--rule) 54%,rgba(179,168,142,0) 100%);
  background-size:100% 1px;
  background-repeat:no-repeat;
  background-position:0 0;
}
.section:first-of-type{background-image:none}
.band .section, .section.band{background-image:none}

/* controls carry the weight; decoration does not */
.field input,.field textarea{border-color:var(--edge)}
.chip span{border-color:var(--edge)}
.opt-mark{border-color:var(--edge)}
.enq .prompt input{border-bottom-color:var(--edge)}
.card{border-color:var(--rule)}

/* a focused or chosen control should read louder than an idle one */
.chip input:not(:checked):hover+span{border-color:var(--ink)}

/* ── corners ──────────────────────────────────────────────────────────────
   4px on the boxes you touch or read from: controls, cards, the contact
   panel. Not on the structural frame — image frames, bands, the selvedge and
   the section rules stay hard, so the softened things read as objects sitting
   on a straight ground rather than the whole page going soft.

   The larger radii already in the stylesheet (10, 16, 18px on route cards and
   framed figures) are deliberate and left alone. */
:root{ --r:4px }

.btn{border-radius:var(--r)}
.card{border-radius:var(--r)}
.chip span{border-radius:var(--r)}
.field input,.field textarea{border-radius:var(--r)}
.begin-card{border-radius:var(--r)}
.stage-tab{border-radius:var(--r)}
.enq .prompt input{border-radius:0}   /* a ruled line, not a box */
