@charset "utf-8";
/* ==========================================================================
   Paragon Textiles Company, design system
   White is the product. The only colour comes from the goods and one gold thread.
   Tokens and rules are specified in /SPEC.md §2-4. Edit there first.
   ========================================================================== */

/* --- 1. Fonts ------------------------------------------------------------ */
@font-face {
  font-family: "Archivo";
  src: url("/assets/fonts/archivo-400_700.woff2") format("woff2-variations");
  font-weight: 400 700;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Plex Mono";
  src: url("/assets/fonts/plexmono-400.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Plex Mono";
  src: url("/assets/fonts/plexmono-500.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: "Cormorant";
  src: url("/assets/fonts/cormorant-500.woff2") format("woff2");
  font-weight: 500;
  font-display: optional;
}
@font-face {
  font-family: "Naskh";
  src: url("/assets/fonts/notonaskh-400.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

/* --- 2. Tokens ----------------------------------------------------------- */
:root {
  /* The page field is the marble/plaster plate lifted from the company profile PDF
     (page background layer, extracted unmodified). --field is its flat fallback, and
     is what paints before the image decodes, keep the two in step. Because body copy
     sits directly on the plate in transparent sections, every text token below is
     measured against #D6D6D6, the 1st-percentile (darkest realistic) marble tone,
     not against white. */
  --field: #eaeaea;
  --paper: #f8f7f5;        /* lifted panel, reads lighter than the marble, as in the PDF */
  --ink: #171717;          /* 12.34:1 on the darkest marble */
  --ink-soft: #3a3a38;     /*  7.84:1 */
  --muted: #55554f;        /*  5.16:1, was #5F5F59, which fell to 4.42:1 on the marble */
  --line: #d8d4cb;         /* decorative hairline, darkened so it survives the texture */
  --line-firm: #cfcac0;    /* table and card borders */
  --control: #767268;      /* form-control boundary, 4.80:1 on white, 3.30:1 on marble.
                              WCAG 1.4.11 needs 3:1 to identify an input, so this cannot
                              be lightened to match the decorative lines. */
  --gold: #cfb082;
  --gold-deep: #b08d4f;
  --gold-ink: #66500c;     /*  5.32:1 on the darkest marble, the only gold allowed as text */
  --green: #00693c;
  --green-lit: #008043;
  --warp: rgba(23, 23, 23, .05);

  --sans: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --mono: "Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --serif: "Cormorant", Georgia, "Times New Roman", serif;

  --wrap: 1360px;
  --pad: clamp(1.25rem, 4vw, 4rem);
  --gap: clamp(1rem, 2vw, 2rem);
  --sect: clamp(4.5rem, 9vw, 8rem);
  --r: 3px;
  --ease: cubic-bezier(.22, .61, .36, 1);
}

/* --- 3. Reset ------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--field);
  color: var(--ink);
  font-family: var(--sans);
  font-size: clamp(1rem, .96rem + .25vw, 1.0625rem);
  line-height: 1.65;
  font-synthesis-weight: none;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, picture, video, svg { display: block; max-width: 100%; }
img { height: auto; background-repeat: no-repeat; background-size: cover; }
h1, h2, h3, h4, p, figure, blockquote, ul, ol, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }
button, input, select, textarea { font: inherit; color: inherit; }
table { border-collapse: collapse; width: 100%; }
a { color: inherit; }

/* --- 4. The field: marble plate + warp ----------------------------------- */
/* Two layers on one fixed pseudo-element: the warp hairlines (the threads on a loom)
   over the marble plate taken from the company profile PDF. Deliberately NOT
   `background-attachment: fixed` on <body>, that repaints on every scroll frame and
   misbehaves on iOS. A fixed pseudo-element gets the same effect for free. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(to right, var(--warp) 0 1px, transparent 1px calc(100% / 6)),
    url("/assets/img/bg/marble-1600.webp");
  background-size: min(var(--wrap), calc(100vw - var(--pad) * 2)) 100%, cover;
  background-position: center top, center center;
  background-repeat: repeat-y, no-repeat;
}
@media (max-width: 720px) {
  body::before {
    background-image:
      repeating-linear-gradient(to right, var(--warp) 0 1px, transparent 1px calc(100% / 3)),
      url("/assets/img/bg/marble-900.webp");
  }
}
body > * { position: relative; z-index: 1; }

/* --- 5. The weft: scroll progress ---------------------------------------- */
.weft {
  position: fixed;
  inset: 0 0 auto 0;
  height: 2px;
  background: var(--gold);
  transform: scaleX(var(--p, 0));
  transform-origin: 0 50%;
  z-index: 90;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) { .weft { display: none; } }

/* --- 6. Typography ------------------------------------------------------- */
.display, h1 {
  font-weight: 700;
  font-stretch: 78%;
  font-size: clamp(2.25rem, 1.5rem + 3.4vw, 4.25rem);
  line-height: 1.02;
  letter-spacing: -.02em;
  text-wrap: balance;
}
h2 {
  font-weight: 600;
  font-stretch: 84%;
  font-size: clamp(1.6rem, 1.2rem + 1.6vw, 2.5rem);
  line-height: 1.1;
  letter-spacing: -.012em;
  text-wrap: balance;
}
h3 { font-weight: 600; font-size: 1.125rem; line-height: 1.3; letter-spacing: -.005em; }
h4 { font-weight: 600; font-size: 1rem; line-height: 1.35; }

p { max-width: 34rem; }
p + p, p + ul, ul + p, p + .btn-row { margin-top: 1em; }
.lede { font-size: clamp(1.0625rem, 1rem + .5vw, 1.3125rem); line-height: 1.5; color: var(--ink-soft); max-width: 36rem; }
.small { font-size: .875rem; line-height: 1.55; color: var(--muted); }

.eyebrow {
  font-family: var(--mono);
  font-weight: 500;
  font-size: .6875rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: .9rem;
}
.eyebrow--gold { color: var(--gold-ink); }

.quote {
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(1.5rem, 1.1rem + 1.7vw, 2.375rem);
  line-height: 1.22;
  letter-spacing: .005em;
  max-width: 22ch;
  color: var(--ink);
}
.quote cite { display: block; margin-top: 1.25rem; font: 500 .6875rem/1.4 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--muted); font-style: normal; }

.mono { font-family: var(--mono); font-size: .8125rem; }
.rule { border: 0; border-top: 1px solid var(--line); margin: 0; }
.rule--gold { border-top-color: var(--gold); }

a:not([class]) { color: var(--ink); text-decoration: underline; text-decoration-color: var(--gold-deep); text-underline-offset: .18em; text-decoration-thickness: 1px; }
a:not([class]):hover { text-decoration-color: var(--ink); }

::selection { background: var(--gold); color: var(--ink); }

:focus-visible { outline: 3px solid var(--green-lit); outline-offset: 2px; border-radius: 2px; }
.on-ink :focus-visible { outline-color: var(--gold); }

.skip-link {
  position: absolute; left: .75rem; top: -4rem; z-index: 200;
  background: var(--ink); color: #fff; padding: .7rem 1.1rem; border-radius: var(--r);
  font: 500 .875rem var(--sans); text-decoration: none; transition: top .15s var(--ease);
}
.skip-link:focus { top: .75rem; }

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

/* --- 7. Layout ----------------------------------------------------------- */
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--pad); }
.grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--gap); }

.section { padding-block: var(--sect); }
.section--tight { padding-block: clamp(3rem, 6vw, 5rem); }
.section--paper { background: var(--paper); }

/* Selvedge: one gold rule on a single edge, alternating down the page. */
.selvedge { position: relative; }
.selvedge::before {
  content: ""; position: absolute; top: 0; bottom: 0; width: 1px;
  background: linear-gradient(to bottom, transparent, var(--gold) 12%, var(--gold) 88%, transparent);
}
.selvedge--l::before { left: 0; }
.selvedge--r::before { right: 0; }
@media (max-width: 900px) { .selvedge::before { display: none; } }

.head { max-width: 46rem; margin-bottom: clamp(2rem, 4vw, 3.25rem); }
.head p { margin-top: 1rem; }

/* --- 8. Utility bar + header --------------------------------------------- */
.utility {
  background: var(--ink);
  color: #efeee9;
  font-family: var(--mono);
  font-size: .6875rem;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.utility .wrap { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 2.25rem; }
.utility a { color: #efeee9; text-decoration: none; }
.utility a:hover { color: var(--gold); }
.utility nav { display: flex; gap: 1.5rem; }
@media (max-width: 900px) { .utility { display: none; } }

header.site {
  position: sticky; top: 0; z-index: 80;
  background: rgba(255, 255, 255, .72);
  backdrop-filter: saturate(150%) blur(14px);
  border-bottom: 1px solid var(--line);
}
header.site .wrap { display: flex; align-items: center; gap: 1.5rem; min-height: 4.5rem; }
/* This breakpoint is intentionally 1024px, not the site's usual 900px: with the lockup now
   reading "Paragon Textile Company" (was "Paragon Textile"), the full desktop nav plus the
   "Request a Quote" button no longer fit beside it between roughly 901px and 975px, which
   pushed the button off the right edge. Measured via CDP: 0px overflow at 975px, 5px at 965px,
   growing to 66px at 901px. 1024px clears that zone with margin for real browser chrome
   (scrollbars, font hinting) that a headless measurement does not account for. */
@media (max-width: 1024px) { header.site .wrap { min-height: 3.75rem; } }

/* Logo lockup */
.lockup { display: flex; align-items: center; gap: .7rem; text-decoration: none; flex: 0 0 auto; }
.lockup img { width: 34px; height: 34px; }
.lockup b {
  display: block; font-family: var(--serif); font-weight: 500; font-size: 1.0625rem;
  letter-spacing: .09em; text-transform: uppercase; line-height: 1.05; color: var(--ink);
  white-space: nowrap;
}
.lockup span {
  display: block; font-family: var(--mono); font-size: .5rem; letter-spacing: .22em;
  text-transform: uppercase; color: var(--muted); margin-top: .18rem;
}
@media (max-width: 420px) { .lockup b { font-size: .9375rem; } .lockup img { width: 28px; height: 28px; } }

/* Desktop nav */
.nav { display: flex; align-items: center; gap: .25rem; margin-left: auto; }
.nav > li { position: relative; }
.nav a, .nav button.top {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .55rem .7rem; font-size: .875rem; font-weight: 500;
  text-decoration: none; color: var(--ink); background: none; border: 0; cursor: pointer;
  border-radius: var(--r);
}
.nav a:hover, .nav button.top:hover { background: var(--paper); }
.nav a[aria-current="page"] { box-shadow: inset 0 -2px 0 var(--gold-deep); }
.nav button.top svg { width: 9px; height: 9px; transition: transform .18s var(--ease); }
.nav li[data-open="true"] button.top svg { transform: rotate(180deg); }

.panel {
  position: absolute; top: calc(100% + .4rem); left: 50%; translate: -50% 0;
  min-width: 20rem; padding: .75rem; background: #fff;
  border: 1px solid var(--line-firm); border-radius: var(--r);
  box-shadow: 0 18px 44px -28px rgba(23, 23, 23, .5);
  display: none;
}
.nav li[data-open="true"] .panel { display: block; }
.panel ul { display: grid; grid-template-columns: 1fr 1fr; gap: 1px 0; }
.panel--one ul { grid-template-columns: 1fr; }
.panel a { display: block; padding: .5rem .65rem; font-size: .8125rem; white-space: nowrap; }
.panel .panel-head { font: 500 .625rem/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--muted); padding: .35rem .65rem .6rem; }

.nav-cta { margin-left: .5rem; }
@media (max-width: 1180px) { .nav a, .nav button.top { padding: .55rem .5rem; font-size: .8125rem; } }
/* .nav-cta is also a .btn, which is declared later, so this needs the extra specificity. */
@media (max-width: 1024px) { .nav, header.site .nav-cta { display: none; } }

/* Mobile nav */
.burger {
  display: none; margin-left: auto; width: 2.75rem; height: 2.75rem;
  align-items: center; justify-content: center;
  background: none; border: 1px solid var(--line-firm); border-radius: var(--r); cursor: pointer;
}
.burger span { display: block; width: 18px; height: 1.5px; background: var(--ink); position: relative; }
.burger span::before, .burger span::after { content: ""; position: absolute; left: 0; width: 18px; height: 1.5px; background: var(--ink); }
.burger span::before { top: -6px; } .burger span::after { top: 6px; }
.burger[aria-expanded="true"] span { background: transparent; }
.burger[aria-expanded="true"] span::before { top: 0; rotate: 45deg; }
.burger[aria-expanded="true"] span::after { top: 0; rotate: -45deg; }
@media (max-width: 1024px) { .burger { display: inline-flex; } }

.mnav {
  position: fixed; inset: 0; z-index: 95; background: var(--field);
  padding: 4.5rem var(--pad) 2rem; overflow-y: auto; display: none;
}
.mnav[data-open="true"] { display: block; }
body[data-lock="true"] { overflow: hidden; }
.mnav > ul > li { border-bottom: 1px solid var(--line); }
/* Scoped to the nav list only, .mfoot holds .btn elements that must keep their own styling. */
.mnav > ul a, .mnav > ul button {
  display: flex; align-items: center; justify-content: space-between; width: 100%;
  padding: 1rem 0; font-size: 1.0625rem; font-weight: 500; text-decoration: none;
  background: none; border: 0; text-align: left; cursor: pointer;
}
.mnav > ul button svg { width: 11px; height: 11px; transition: transform .18s var(--ease); }
.mnav li[data-open="true"] > button svg { transform: rotate(180deg); }
.mnav .sub { display: none; padding: 0 0 .75rem .9rem; border-left: 1px solid var(--gold); }
.mnav li[data-open="true"] > .sub { display: block; }
.mnav .sub a { padding: .5rem 0; font-size: .9375rem; font-weight: 400; color: var(--ink-soft); }
.mnav .mfoot { margin-top: 2rem; display: grid; gap: .75rem; }

/* --- 9. Buttons ---------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .8rem 1.4rem; border-radius: var(--r); border: 1px solid transparent;
  font-size: .875rem; font-weight: 600; text-decoration: none; cursor: pointer;
  transition: background .18s var(--ease), color .18s var(--ease), border-color .18s var(--ease);
}
.btn--primary { background: var(--green); color: #fff; }
.btn--primary:hover { background: #005531; }
.btn--ghost { border-color: var(--control); color: var(--ink); background: #fff; }
.btn--ghost:hover { border-color: var(--ink); }
.btn--ink { background: var(--ink); color: #fff; }
.btn--ink:hover { background: #000; }
.btn--sm { padding: .55rem 1rem; font-size: .8125rem; }
.btn-row { display: flex; flex-wrap: wrap; gap: .75rem; align-items: center; }
/* Buttons keep their appearance inside contexts that restyle bare <a> elements
   (the footer, the utility bar, the mobile nav). Doubled class = higher specificity. */
.btn.btn--primary { background: var(--green); color: #fff; }
.btn.btn--ghost { background: #fff; color: var(--ink); border-color: var(--control); }
.btn.btn--ink { background: var(--ink); color: #fff; }

.link-arrow {
  display: inline-flex; align-items: center; gap: .4rem;
  font-family: var(--mono); font-size: .75rem; letter-spacing: .1em; text-transform: uppercase;
  text-decoration: none; color: var(--ink); padding-bottom: .18rem;
  border-bottom: 1px solid var(--gold-deep);
}
.link-arrow:hover { border-bottom-color: var(--ink); }
.link-arrow::after { content: "→"; transition: transform .18s var(--ease); }
@media (prefers-reduced-motion: no-preference) { .link-arrow:hover::after { transform: translateX(3px); } }

/* --- 10. Breadcrumb ------------------------------------------------------ */
.breadcrumb { padding-block: 1.1rem .25rem; }
/* Accepts either <nav class="breadcrumb"><ol> or <ol class="breadcrumb">. */
.breadcrumb ol, ol.breadcrumb { display: flex; flex-wrap: wrap; gap: .45rem; font-family: var(--mono); font-size: .6875rem; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.breadcrumb li + li::before { content: "/"; margin-right: .45rem; color: var(--line-firm); }
.breadcrumb a { color: var(--muted); text-decoration: none; }
.breadcrumb a:hover { color: var(--ink); }
.breadcrumb [aria-current="page"] { color: var(--ink); }

/* --- 11. Hero (portrait-first split) ------------------------------------- */
.hero { padding-block: clamp(2.5rem, 5vw, 5rem) clamp(3.5rem, 7vw, 6.5rem); }
.hero .grid { align-items: center; row-gap: clamp(2rem, 4vw, 3rem); }
/* min-width: 0 overrides the grid default of min-width: auto, which sizes a grid
   item to fit its content's intrinsic width, not its track. Left unset, a wide
   image or a long heading forces the item wider than its column and the excess
   is silently clipped by overflow-x on body, instead of wrapping or scaling down. */
.hero-copy { grid-column: 1 / span 6; min-width: 0; }
.hero-art { grid-column: 8 / span 5; min-width: 0; }
.hero-art figure { position: relative; }
.hero-art img { border-radius: var(--r); width: 100%; }
.hero h1 { margin-bottom: 1.25rem; }
.hero .lede { margin-bottom: 1.75rem; }
@media (max-width: 900px) {
  .hero-copy, .hero-art { grid-column: 1 / -1; }
  .hero-art { order: -1; max-width: 30rem; }
}

/* Caption plate that sits on the corner of a photo */
.plate {
  position: absolute; left: 0; bottom: 0; background: #fff;
  padding: .8rem 1rem; border-top: 1px solid var(--gold); max-width: 72%;
  font-family: var(--mono); font-size: .6875rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted);
}

/* --- 12. Editorial blocks ------------------------------------------------ */
.split { align-items: center; row-gap: clamp(2rem, 4vw, 3rem); }
.split > .col-text, .split > .col-art { min-width: 0; }
.split > .col-text { grid-column: 1 / span 5; }
.split > .col-art { grid-column: 7 / span 6; }
.split.is-flipped > .col-text { grid-column: 8 / span 5; }
.split.is-flipped > .col-art { grid-column: 1 / span 6; }
/* Both columns share one row so a flipped block does not wrap to a second row. */
@media (min-width: 901px) { .split > .col-text, .split > .col-art { grid-row: 1; } }
@media (max-width: 900px) {
  .split > .col-text, .split > .col-art,
  .split.is-flipped > .col-text, .split.is-flipped > .col-art { grid-column: 1 / -1; }
  .split.is-flipped > .col-art { order: -1; }
}

/* Two photos, side by side, each with its own caption, e.g. a pair of award shots. */
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.25rem, 3vw, 2rem); }
.pair > * { min-width: 0; }
@media (max-width: 700px) { .pair { grid-template-columns: 1fr; } }
.pair figure { margin: 0; }
.pair img { width: 100%; height: auto; border-radius: var(--r); }

figure figcaption {
  margin-top: .75rem; font-family: var(--mono); font-size: .6875rem;
  letter-spacing: .06em; color: var(--muted); max-width: 34rem;
}

/* --- 13. Cards ----------------------------------------------------------- */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr)); gap: clamp(1rem, 2vw, 1.75rem); }
.cards--2 { grid-template-columns: repeat(auto-fill, minmax(22rem, 1fr)); }
.card {
  position: relative; display: flex; flex-direction: column;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r); overflow: hidden;
  transition: border-color .2s var(--ease);
}
.card:hover, .card:focus-within { border-color: var(--gold-deep); }
.card .shot { aspect-ratio: 4 / 5; overflow: hidden; background: var(--paper); }
.card .shot picture { display: block; height: 100%; }
.card .shot img { width: 100%; height: 100%; object-fit: cover; }
@media (prefers-reduced-motion: no-preference) {
  .card .shot img { transition: transform .5s var(--ease); }
  .card:hover .shot img, .card:focus-within .shot img { transform: scale(1.035); }
}
.card .body { padding: 1.1rem 1.15rem 1.35rem; display: flex; flex-direction: column; gap: .45rem; flex: 1; }
.card h3 a { text-decoration: none; }
.card h3 a::after { content: ""; position: absolute; inset: 0; }
.card p { font-size: .875rem; color: var(--muted); margin: 0; }
.card .tag { font-family: var(--mono); font-size: .625rem; letter-spacing: .14em; text-transform: uppercase; color: var(--gold-ink); }

/* --- 14. Spec tables ----------------------------------------------------- */
.table-scroll { overflow-x: auto; border: 1px solid var(--line-firm); border-radius: var(--r); }
.table-scroll:focus-visible { outline-offset: 0; }
.spec-table { font-size: .9375rem; min-width: 30rem; }
.spec-table caption { text-align: left; padding: .9rem 1rem; font: 500 .6875rem/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--muted); border-bottom: 1px solid var(--line-firm); }
.spec-table th, .spec-table td { text-align: left; padding: .75rem 1rem; vertical-align: top; border-top: 1px solid var(--line); }
.spec-table thead th { font-size: .75rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); border-top: 0; background: var(--paper); }
.spec-table tbody th { font-weight: 600; width: 32%; }
.spec-table tbody tr:nth-child(even) { background: var(--paper); }
.spec-table td em { font-style: normal; color: var(--muted); }

.spec-pill {
  display: inline-block; margin-left: .4rem; padding: .1rem .45rem;
  font-family: var(--mono); font-size: .625rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); background: #fff; border: 1px solid var(--line-firm); border-radius: 999px;
  white-space: nowrap; vertical-align: 1px;
}
.spec-note { margin-top: .75rem; font-size: .8125rem; color: var(--muted); max-width: 40rem; }

@media (max-width: 620px) {
  .table-scroll { border: 0; }
  .spec-table, .spec-table tbody, .spec-table tr { display: block; min-width: 0; }
  .spec-table thead { display: none; }
  .spec-table caption { padding-inline: 0; }
  .spec-table tr { border: 1px solid var(--line-firm); border-radius: var(--r); margin-bottom: .75rem; padding: .35rem .9rem .6rem; background: #fff !important; }
  .spec-table th, .spec-table td { display: block; width: auto; padding: .35rem 0; border: 0; }
  .spec-table tbody th { font-size: .6875rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); border-bottom: 1px solid var(--line); padding-bottom: .3rem; }
  .spec-table td[data-label]::before { content: attr(data-label); display: block; font: 500 .625rem/1.4 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
}

/* --- 15. Roster (organisations served) ----------------------------------- */
.roster { border-top: 1px solid var(--gold); }
.roster ul { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }
.roster li {
  padding: 1.05rem .25rem; border-bottom: 1px solid var(--line);
  font-family: var(--serif); font-weight: 500; font-size: 1.375rem; letter-spacing: .01em;
}
.roster li span { display: block; font: 400 .625rem/1.4 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--muted); margin-top: .15rem; }

/* --- 15b. Logo strip (organisations supplied) -----------------------------
   Marks only, centred, on one horizontal line that wraps.

   Each file is emitted tightly cropped at a size already balanced by ink area
   (tools/normalise_logos.py), and carries its own width/height, so a single flex
   gap does all the spacing and every mark sits on a shared centre line without any
   per-logo CSS. Flex wrapping also centres the final row automatically, which is
   what a grid could not do with eleven items.

   The organisation name lives in each image's alt attribute; it is what a screen
   reader announces and what a crawler reads now that the captions are gone. */
.logostrip {
  --k: 1;                       /* one responsive multiplier for every mark */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(2rem, 3.5vw, 3.25rem) clamp(2.25rem, 4vw, 4rem);
  /* Anchored on the site's own white-panel-over-marble language. Loose marks
     floating on the texture read as unfinished, and the coloured logos need a
     neutral ground to sit on. The max-width also forces a more even wrap than
     the full container does. */
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: clamp(2rem, 3.5vw, 2.75rem) clamp(1.75rem, 4vw, 3.25rem);
  /* Shrink to the marks it actually holds. Several pages show only one or three
     organisations, and a full-width panel around a single logo reads as a mistake;
     fit-content keeps the panel proportional to its contents at every count. */
  width: fit-content;
  max-width: min(68rem, 100%);
  margin-inline: auto;
}
.logostrip li { display: flex; align-items: center; }
/* Width comes from each item's own --w, set inline by tools/update_logostrip.py and
   already balanced by ink area. Height stays auto so the aspect ratio holds. A
   shared max-height would force every mark to the same height and undo that work. */
.logostrip img {
  display: block;
  width: calc(var(--w, 140) * var(--k) * 1px);
  height: auto;
  max-width: 100%;
}
@media (max-width: 1080px) { .logostrip { --k: .84; } }
@media (max-width: 700px)  { .logostrip { --k: .66; gap: 1.75rem 2.25rem; } }
@media (max-width: 420px)  { .logostrip { --k: .56; gap: 1.5rem 1.75rem; } }

/* --- 16. Facts strip ----------------------------------------------------- */
.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.facts > div { background: #fff; padding: 1.35rem 1.25rem; }
.facts dt { font: 500 .625rem/1.4 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.facts dd { margin-top: .4rem; font-size: 1rem; font-weight: 600; line-height: 1.35; overflow-wrap: anywhere; }

/* --- 17. Accordion (FAQ) ------------------------------------------------- */
.accordion { border-top: 1px solid var(--line); }
.accordion details { border-bottom: 1px solid var(--line); }
.accordion summary {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1.5rem;
  padding: 1.15rem 0; cursor: pointer; font-weight: 600; font-size: 1.0625rem; list-style: none;
}
.accordion summary::-webkit-details-marker { display: none; }
.accordion summary::after { content: "+"; font-family: var(--mono); font-weight: 400; color: var(--gold-ink); flex: 0 0 auto; }
.accordion details[open] summary::after { content: "-"; }
.accordion .answer { padding-bottom: 1.35rem; }
.accordion .answer p { color: var(--ink-soft); }

/* --- 18. Gallery scroller ------------------------------------------------ */
.scroller {
  display: flex; gap: 1rem; overflow-x: auto; scroll-snap-type: x mandatory;
  padding-bottom: 1rem; scroll-padding-left: var(--pad);
}
.scroller > * { flex: 0 0 min(78vw, 22rem); scroll-snap-align: start; }
.scroller img { width: 100%; border-radius: var(--r); }
.scroller-ctl { display: flex; gap: .5rem; margin-top: .75rem; }
.scroller-ctl button { width: 2.5rem; height: 2.5rem; border: 1px solid var(--control); background: #fff; border-radius: var(--r); cursor: pointer; }
.scroller-ctl button:hover { border-color: var(--ink); }

.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); gap: .75rem; }
.tiles img { width: 100%; border-radius: var(--r); }

/* --- 19. Video panel ------------------------------------------------------
   The clip is shot on a phone, so it is portrait, while the factory stills
   beside it are landscape. Stacking the two at their own widths left a ragged
   column and a tower of video next to a short paragraph. They are paired in one
   fixed-ratio band instead: the portrait clip keeps a portrait cell, the still
   gets a wider one, and both resolve to exactly the same height. */
.media-pair {
  display: grid; grid-template-columns: 0.72fr 1fr; gap: clamp(.6rem, 1.4vw, 1rem);
  aspect-ratio: 1.85 / 1; align-items: stretch;
}
.media-pair > * { margin: 0; min-width: 0; height: 100%; }
.media-pair .loom, .media-pair figure { position: relative; }
/* <picture> is only a wrapper, so the height has to be passed through it or the
   still collapses to its own aspect and the two cells stop lining up. */
.media-pair picture { display: block; height: 100%; }
/* The still is landscape in a tall cell, so bias the crop up off the floor and
   onto the looms themselves. */
.media-pair figure img { object-position: center 22%; }
.media-pair video, .media-pair img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  border-radius: var(--r); background: var(--paper);
}
/* The control sits on the clip, so the pair keeps one clean baseline and the
   button reads as a player rather than a stray form field. */
.media-pair .ctl { position: absolute; left: .6rem; bottom: .6rem; margin: 0; }
.media-pair .ctl .btn { background: rgba(255,255,255,.94); backdrop-filter: blur(3px); }
.media-cap { margin-top: .8rem; }
@media (max-width: 520px) { .media-pair { aspect-ratio: 1.5 / 1; } }

/* Standalone use (no pair): keep the clip to a sane column width. */
.loom { max-width: 22rem; }
.loom video, .loom img { width: 100%; aspect-ratio: 540 / 960; object-fit: cover; border-radius: var(--r); background: var(--paper); }
.loom .ctl { margin-top: .6rem; display: flex; align-items: center; gap: .75rem; }
.media-pair .loom { max-width: none; }
.media-pair .loom video { aspect-ratio: auto; }

/* --- 20. Forms ----------------------------------------------------------- */
.rfq { display: grid; gap: 1.5rem; max-width: 44rem; }
.fieldset { border: 0; padding: 0; margin: 0; display: grid; gap: 1rem; }
.fieldset legend { font: 500 .6875rem/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--muted); padding: 0 0 .9rem; }
.f2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.f2 > * { min-width: 0; }
@media (max-width: 620px) { .f2 { grid-template-columns: 1fr; } }

.field { display: grid; gap: .35rem; }
.field > label { font-size: .8125rem; font-weight: 600; }
.field .req { color: var(--green); }
.field input, .field select, .field textarea {
  width: 100%; padding: .7rem .8rem; background: #fff;
  border: 1px solid var(--control); border-radius: var(--r); font-size: .9375rem;
}
.field textarea { min-height: 8rem; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--ink); }
.field [aria-invalid="true"] { border-color: #a4262c; }
.field-error { font-size: .8125rem; color: #a4262c; min-height: 0; }
.field-hint { font-size: .8125rem; color: var(--muted); }

.checks { display: grid; grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr)); gap: .5rem 1rem; }
.checks label { display: flex; align-items: center; gap: .5rem; font-size: .875rem; }
.checks input { width: 1rem; height: 1rem; accent-color: var(--green); }

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

.form-terms { background: var(--paper); border: 1px solid var(--line); border-radius: var(--r); padding: 1rem 1.15rem; font-size: .875rem; }
.form-terms ul { display: grid; gap: .35rem; }
.form-terms li { padding-left: 1.1rem; position: relative; color: var(--ink-soft); }
.form-terms li::before { content: ""; position: absolute; left: 0; top: .62em; width: 6px; height: 1px; background: var(--gold-deep); }
.form-status { font-size: .875rem; font-weight: 600; }

/* --- 21. Footer ---------------------------------------------------------- */
footer.site { background: var(--ink); color: #d9d7d0; padding-block: clamp(3rem, 6vw, 4.5rem) 2rem; margin-top: var(--sect); }
footer.site h2, footer.site h3 { color: #fff; }
footer.site a { color: #d9d7d0; text-decoration: none; }
footer.site a:hover { color: var(--gold); }
.fgrid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.2fr; gap: clamp(1.5rem, 3vw, 3rem); }
.fgrid > * { min-width: 0; }
@media (max-width: 900px) { .fgrid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .fgrid { grid-template-columns: 1fr; } }
.fgrid h3 { font: 500 .625rem/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: #93918a; margin-bottom: 1rem; }
.fgrid li { padding: .28rem 0; font-size: .875rem; }
footer.site .lockup b { color: #fff; }
footer.site .lockup span { color: #93918a; }
footer.site address { font-style: normal; font-size: .875rem; line-height: 1.7; }
.fbottom { margin-top: clamp(2.5rem, 5vw, 3.5rem); padding-top: 1.5rem; border-top: 1px solid #2e2e2b; display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between; font-family: var(--mono); font-size: .6875rem; letter-spacing: .06em; color: #93918a; }

/* --- 22. WhatsApp button ------------------------------------------------- */
.wa-fab {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 70;
  display: none; align-items: center; gap: .5rem;
  padding: .7rem 1rem; background: #1f8a4c; color: #fff; border-radius: 999px;
  font-size: .8125rem; font-weight: 600; text-decoration: none;
  box-shadow: 0 10px 30px -12px rgba(0, 0, 0, .5);
}
@media (max-width: 900px) { .wa-fab { display: inline-flex; } }

/* --- 23. Prose (blog) ---------------------------------------------------- */
.prose { max-width: 38rem; }
.prose h2 { margin-top: 2.75rem; margin-bottom: .85rem; font-size: clamp(1.375rem, 1.1rem + 1vw, 1.875rem); }
.prose h3 { margin-top: 1.9rem; margin-bottom: .5rem; }
.prose p, .prose ul, .prose ol { margin-bottom: 1.1rem; }
.prose ul li, .prose ol li { padding-left: 1.35rem; position: relative; margin-bottom: .4rem; }
.prose ul li::before { content: ""; position: absolute; left: 0; top: .72em; width: 8px; height: 1px; background: var(--gold-deep); }
.prose ol { counter-reset: n; }
.prose ol li { counter-increment: n; }
.prose ol li::before { content: counter(n) "."; position: absolute; left: 0; font-family: var(--mono); font-size: .8125rem; color: var(--gold-ink); }
.prose .table-scroll { margin-bottom: 1.5rem; }

.meta { font-family: var(--mono); font-size: .6875rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }

/* --- 24. Arabic / Urdu --------------------------------------------------- */
[lang="ar"], [lang="ur"] { font-family: "Naskh", serif; font-size: 1.15em; line-height: 2; }

/* --- 25. Motion (opt-in) ------------------------------------------------- */
/* .reveal is VISIBLE by default. The hidden start state is applied only after JS has
   confirmed it can observe the element and reveal it again, so content can never be
   stranded invisible by a blocked script, a failed observer or a scroll-timeline quirk. */
@media (prefers-reduced-motion: no-preference) {
  html[data-io] .reveal { opacity: 0; transform: translateY(14px); transition: opacity .55s var(--ease), transform .55s var(--ease); }
  html[data-io] .reveal.is-in { opacity: 1; transform: none; }

  @view-transition { navigation: auto; }
  ::view-transition-old(root) { animation: vt-out .24s ease both; }
  ::view-transition-new(root) { animation: vt-in .3s ease both; }
  @keyframes vt-out { to { opacity: 0; } }
  @keyframes vt-in { from { opacity: 0; transform: translateY(10px); } }
}

/* --- 26. Print ----------------------------------------------------------- */
@media print {
  body::before, .weft, .utility, .burger, .nav-cta, .wa-fab, .mnav, .scroller-ctl { display: none !important; }
  header.site { position: static; border-bottom: 1px solid #999; }
  body { font-size: 11pt; line-height: 1.45; color: #000; background: #fff; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }
  .card, .spec-table, .facts, figure, .accordion details { break-inside: avoid; }
  .accordion details { display: block; }
  .accordion .answer { display: block !important; }
  footer.site { background: none; color: #000; }
  footer.site a, footer.site .lockup b { color: #000; }
  .section { padding-block: 1.2rem; }
}
