/* ==================================================================
   KYNA WATER SOLUTIONS - block stylesheet

   Section-level layout families. Each family appears at most once per
   page, so the scroll never repeats its own rhythm.

   Sizes come from the fluid scale in kyna.css. Media queries here only
   change structure (how many columns, which order), never size.
   ================================================================== */

/* -- 1. Hero (asymmetric split) ----------------------------------- */
.hero { padding: calc(var(--hdr-h) + var(--sp-xl)) 0 var(--sp-xl); }
.hero-grid {
  display: grid;
  grid-template-columns: 1.08fr 0.92fr;
  gap: var(--sp-xl);
  align-items: center;
}
.hero h1 {
  font-family: var(--font-d); font-weight: 400;
  font-variation-settings: "opsz" 96;
  /* the min() only bites below ~305px, where the clamp floor would
     still be wide enough to break the headline onto a third line */
  font-size: min(var(--t-h1), 10.5vw);
  line-height: 1.04; letter-spacing: -0.022em; color: var(--text);
  margin-bottom: var(--sp-s);
  text-wrap: balance;
}
.hero h1 em {
  font-style: italic; font-variation-settings: "opsz" 96; color: var(--gold-display);
  line-height: 1.14; padding-bottom: 0.08em; display: inline-block;
}
.hero p {
  font-size: var(--t-lead); font-weight: 300; line-height: 1.68;
  color: var(--text-dim); max-width: 44ch; margin-bottom: var(--sp-m);
}

/* Text-led variant, used when the hero carries no figure. Without this
   the single child would sit in the 1.08fr column and leave the other
   46% of the row empty. It takes a reading measure rather than letting
   the headline stretch the full width of the container.
   .is-solo is currently unused: the hero carries the RO skid drawing.
   It is kept because it is the variant to reach for if that ever comes
   out again, and because a hero with no figure needs the wider measure
   or it reads as a headline stranded in a half-empty row. */
.hero-grid.is-solo { grid-template-columns: minmax(0, 1fr); }
.hero-grid.is-solo > div { max-width: 46rem; }
.hero-grid.is-solo p { max-width: 52ch; }

.hero-fig { position: relative; }
.hero-fig .frame {
  position: relative; overflow: hidden;
  border-radius: var(--r);
  background: var(--plate);
  border: 1px solid var(--line);
  aspect-ratio: 4 / 4.5;
  box-shadow: var(--shadow-lg);
}
.hero-fig img { width: 100%; height: 100%; object-fit: cover; object-position: center; }
/* the photography is cool-lit; a low warm wash ties it to the brand
   without touching the hardware itself */
.hero-fig .frame::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(155deg, rgba(201,149,42,0.14), transparent 44%, rgba(7,30,27,0.5));
}
.fig-cap {
  margin-top: var(--sp-xs);
  font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--text-mut);
}

/* Stacked, the message leads and the photograph follows. Putting the
   image first here is what pushed the CTA below the fold at 768px. */
@media (max-width: 900px) {
  .hero-grid { grid-template-columns: 1fr; gap: var(--sp-l); }
  .hero-fig .frame { aspect-ratio: 16 / 9; }
  .hero p { max-width: none; }
}

/* -- 2. Fact rail (no dividers, whitespace does the work) --------- */
.facts { border-top: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft); }
/* Four facts, and auto-fit was orphaning the fourth. Between roughly
   800px and 1100px minmax(220px) fits three across, so the strip read
   3 + 1 with a lone card on its own row. Explicit counts instead:
   4 across when there is room, then 2 x 2, then stacked. Structure
   only, no size token is touched, per the rule at the top of this file. */
.facts-grid {
  display: grid; gap: var(--sp-l) var(--sp-m);
  grid-template-columns: repeat(4, minmax(0, 1fr));
  padding: var(--sp-xl) 0;
}
@media (max-width: 1040px) { .facts-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px)  { .facts-grid { grid-template-columns: minmax(0, 1fr); } }
.fact i { font-size: 1.5rem; color: var(--gold); display: block; margin-bottom: var(--sp-xs); }
.fact b { display: block; font-size: var(--t-body); font-weight: 500; color: var(--text); margin-bottom: var(--sp-3xs); }
.fact span { font-size: var(--t-small); line-height: 1.65; color: var(--text-dim); }

/* -- 3. Report panel (an instrument readout, not a paper sheet) --- */
.report-grid {
  display: grid; grid-template-columns: 0.94fr 1.06fr;
  gap: var(--sp-xl); align-items: center;
}
.report {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow-lg), inset 0 1px 0 var(--inset-hl);
  overflow: hidden;
}
.report-hd {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-s); flex-wrap: wrap;
  padding: var(--sp-s) var(--sp-m);
  border-bottom: 1px solid var(--line);
  background: linear-gradient(var(--sheen), transparent);
}
.report-hd strong { font-family: var(--font-d); font-size: var(--t-lead); font-weight: 400; letter-spacing: 0.01em; color: var(--text); }
.report-hd span { font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold); }
.report-row {
  display: grid; grid-template-columns: 1.3fr 0.8fr 0.8fr auto;
  gap: var(--sp-2xs); align-items: center;
  padding: var(--sp-xs) var(--sp-m);
}
.report-row + .report-row { border-top: 1px solid var(--line-soft); }
.report-row.is-head {
  font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--text-mut);
  border-top: 0; padding-top: var(--sp-s); padding-bottom: var(--sp-2xs);
}
.report-row .p { font-size: var(--t-small); font-weight: 400; color: var(--text); }
.report-row .v { font-family: var(--font-m); font-size: var(--t-small); color: var(--text); }
.report-row .l { font-family: var(--font-m); font-size: var(--t-micro); color: var(--text-dim); }
.flag {
  justify-self: end;
  font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.12em; text-transform: uppercase;
  padding: 0.2em 0.6em; border-radius: var(--r); border: 1px solid;
}
/* gold means "this is the reason you would buy something". Everything
   else is quiet. One accent, doing semantic work. */
.flag-high { color: var(--gold-lit); border-color: rgba(201,149,42,0.42); background: rgba(201,149,42,0.1); }
.flag-ok   { color: var(--flag-ok); border-color: var(--flag-ok-line); background: transparent; }
.report-ft {
  padding: var(--sp-s) var(--sp-m); border-top: 1px solid var(--line-soft);
  font-size: var(--t-micro); line-height: 1.7; color: var(--text-dim);
}
.report-list { list-style: none; display: grid; gap: var(--sp-s); margin-top: var(--sp-m); }
.report-list li { display: flex; gap: var(--sp-xs); align-items: flex-start; font-size: var(--t-small); line-height: 1.7; color: var(--text-dim); }
.report-list i { color: var(--gold); font-size: 1.2rem; flex-shrink: 0; margin-top: 0.1em; }
.report-list b { color: var(--text); font-weight: 500; }

@media (max-width: 900px) {
  .report-grid { grid-template-columns: 1fr; gap: var(--sp-l); }
}
@media (max-width: 560px) {
  .report-row { grid-template-columns: 1fr auto; row-gap: var(--sp-3xs); }
  .report-row .l { display: none; }
  .report-row.is-head { display: none; }
  .report-row .v { grid-column: 1; color: var(--text-dim); }
  .report-row .p { grid-column: 1; }
  .flag { grid-row: 1 / span 2; grid-column: 2; align-self: center; }
}

/* -- 4. Systems bento (exactly as many cells as there is content) - */
.sys-grid {
  display: grid; gap: var(--sp-s);
  grid-template-columns: repeat(auto-fit, minmax(min(360px, 100%), 1fr));
  /* Each card spans the full width, so the two sit in separate implicit
     rows with nothing relating them: one card's height came from its
     drawing, the other's from its body text, and they landed 53px apart.
     This makes every row the height of the tallest, so the cards match at
     any width, and the art panel stretches with the card so the panels
     match too. The drawings are untouched and stay centred. */
  grid-auto-rows: 1fr;
}
.cell {
  position: relative; overflow: hidden;
  border-radius: var(--r); border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: inset 0 1px 0 var(--inset-hl);
  display: flex; flex-direction: column;
  transition: border-color 0.4s var(--ease-2), transform 0.5s var(--ease);
}
.cell:hover { border-color: var(--gold-dim); }
/* The art column carries a landscape drawing that can only grow
   sideways, so it takes the larger share. The body column still holds a
   comfortable measure for the bullets at this split. */
.cell-a { grid-column: 1 / -1; display: grid; grid-template-columns: 1.18fr 0.82fr; }
.cell-art {
  position: relative; min-height: clamp(220px, 26vw, 320px);
  background: var(--plate);
  display: flex; align-items: center; justify-content: center;
  padding: var(--sp-m);
  overflow: hidden;
  border-bottom: 1px solid var(--line-soft);
}
.cell-a .cell-art { border-bottom: 0; border-right: 1px solid var(--line-soft); }
.cell-art > img { width: 100%; height: 100%; object-fit: cover; position: absolute; inset: 0; }
.cell-art .tint { position: absolute; inset: 0; background: linear-gradient(155deg, rgba(201,149,42,0.14), transparent 44%, rgba(7,30,27,0.55)); }
/* a drawing is read, never cropped */
.cell-art.is-draw > img,
.cell-art.is-draw > svg {
  position: relative; inset: auto;
  width: auto; height: auto;
  max-width: 100%; max-height: clamp(200px, 24vw, 300px);
  object-fit: contain;
}
.cell-a .cell-art.is-draw { padding: var(--sp-2xs); }
.cell-a .cell-art.is-draw > img,
.cell-a .cell-art.is-draw > svg {
  width: 100%;
  /* No height cap, on purpose. A landscape drawing is already bounded
     by its own aspect ratio once the width is set: at 100% of the
     panel the RO skid comes out about four fifths as tall as it is
     wide, which cannot dominate the card. A cap here protects nothing
     and starves the drawing instead, and a viewport clamp is the wrong
     shape for it, because this height follows the column and the
     column is not the viewport. The clamp that used to sit here
     floored at 210px on a phone, which letterboxed the drawing down to
     246px across inside a 332px panel, and capped at 442px on a
     1300px screen, throwing away 86px of width there.
     Portrait drawings are the ones that need bounding, and .is-tall
     below bounds them by width, which is the same argument. */
  max-height: none;
}
/* A portrait drawing in a landscape slot: the width above would letterbox
   it down to a third of the panel. Bound it by width instead, the same way
   the product article does, so it fills a narrow card and still stops
   short of dominating a wide one. */
.cell-a .cell-art.is-draw.is-tall > img,
.cell-a .cell-art.is-draw.is-tall > svg { width: clamp(220px, 100%, 347px); height: auto; max-height: none; }
/* faint drafting grid behind the schematics */
.cell-art.is-draw::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(rgba(201,149,42,0.05) 1px, transparent 1px) 0 0 / 100% 38px,
    linear-gradient(90deg, rgba(201,149,42,0.05) 1px, transparent 1px) 0 0 / 38px 100%;
  mask-image: radial-gradient(70% 70% at 50% 50%, #000, transparent);
  -webkit-mask-image: radial-gradient(70% 70% at 50% 50%, #000, transparent);
}
.cell-body { padding: var(--sp-m); display: flex; flex-direction: column; flex: 1; }
.cell-tag {
  font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--gold); margin-bottom: var(--sp-xs);
}
.cell h3 {
  font-family: var(--font-d); font-weight: 400; font-size: var(--t-h3);
  line-height: 1.16; letter-spacing: -0.012em; color: var(--text); margin-bottom: var(--sp-2xs);
}
.cell-body > p:not(.cell-tag) { font-size: var(--t-small); line-height: 1.72; color: var(--text-dim); margin-bottom: var(--sp-s); }
.cell ul { list-style: none; display: grid; gap: var(--sp-2xs); margin-bottom: var(--sp-m); }
.cell li { position: relative; padding-left: var(--sp-s); font-size: var(--t-small); line-height: 1.62; color: var(--text-dim); }
.cell li::before { content: ""; position: absolute; left: 0; top: 0.68em; width: 8px; height: 1px; background: var(--gold); }
.cell .link-arrow { margin-top: auto; align-self: flex-start; }
@media (max-width: 900px) {
  .cell-a { grid-template-columns: 1fr; }
  .cell-a .cell-art { border-right: 0; border-bottom: 1px solid var(--line-soft); }
}

/* Mode switch: buy / rent, and for homes / for sites.
   A padded track with the live segment filled, rather than two buttons
   sharing a divider. The fill then reads as a position within one
   control instead of one button looking permanently pressed. It wraps
   rather than overflowing, which only bites below ~300px. */
.mode {
  display: inline-flex; flex-wrap: wrap; gap: 2px;
  /* inline-flex still stretches as a flex child, which inside a card body
     leaves an empty stretch of track to the right of the last segment */
  align-self: flex-start;
  max-width: 100%; padding: 3px; margin-bottom: var(--sp-m);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: inset 0 1px 0 var(--inset-hl);
}
.mode button {
  font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.14em; text-transform: uppercase;
  padding: var(--sp-2xs) var(--sp-s); white-space: nowrap;
  background: transparent; border: 0; border-radius: var(--r); cursor: pointer;
  color: var(--text-mut); transition: background 0.3s var(--ease-2), color 0.3s var(--ease-2);
}
.mode button:hover { color: var(--text); background: rgba(201,149,42,0.08); }
.mode button.is-on { background: var(--gold-fill); color: var(--ink); }
/* the ring belongs inside the track, not straddling its border */
.mode button:focus-visible { outline-offset: 1px; }

/* -- 5. Process rail ---------------------------------------------- */
.rail { display: grid; grid-template-columns: repeat(5, 1fr); position: relative; }
.rail::before {
  content: ""; position: absolute; left: 0; right: 0;
  top: clamp(24px, 2.2vw, 30px); height: 1px;
  background: linear-gradient(90deg, transparent, var(--line) 8%, var(--line) 92%, transparent);
}
.step { position: relative; padding-right: var(--sp-m); }
.step-dot {
  position: relative; z-index: 1;
  width: clamp(48px, 4.4vw, 60px); height: clamp(48px, 4.4vw, 60px);
  border-radius: var(--r);
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); border: 1px solid var(--line);
  color: var(--gold); font-size: 1.4rem; margin-bottom: var(--sp-s);
}
.step h3 { font-size: var(--t-body); font-weight: 500; color: var(--text); margin-bottom: var(--sp-3xs); letter-spacing: 0.005em; }
.step p { font-size: var(--t-small); line-height: 1.65; color: var(--text-dim); }
@media (max-width: 940px) {
  .rail { grid-template-columns: 1fr; }
  .rail::before { left: clamp(24px, 2.2vw, 30px); right: auto; top: 0; bottom: 0; width: 1px; height: auto;
                  background: linear-gradient(var(--line), var(--line)); }
  .step { display: grid; grid-template-columns: clamp(48px, 4.4vw, 60px) 1fr; gap: var(--sp-s); padding: 0 0 var(--sp-l) 0; }
  .step-dot { margin-bottom: 0; }
}

/* -- 6. Comparison ledger ----------------------------------------- */
.ledger { display: grid; grid-template-columns: 1fr 1fr; border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.ledger-col { padding: var(--sp-m); }
.ledger-col:first-child { background: transparent; }
.ledger-col + .ledger-col {
  border-left: 1px solid var(--line);
  background: var(--surface);
  box-shadow: inset 0 1px 0 var(--inset-hl);
}
.ledger-hd {
  font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--text-mut); padding-bottom: var(--sp-xs); margin-bottom: var(--sp-m); border-bottom: 1px solid var(--line-soft);
}
.ledger-col + .ledger-col .ledger-hd { color: var(--gold); border-color: var(--line); }
.ledger ul { list-style: none; display: grid; gap: var(--sp-s); }
.ledger li { display: flex; gap: var(--sp-2xs); font-size: var(--t-small); line-height: 1.68; color: var(--text-dim); }
.ledger li i { flex-shrink: 0; font-size: 1.15rem; margin-top: 0.08em; color: var(--text-mut); }
.ledger-col + .ledger-col li i { color: var(--gold); }
.ledger-col + .ledger-col li { color: var(--text); }
@media (max-width: 800px) { .ledger { grid-template-columns: 1fr; } .ledger-col + .ledger-col { border-left: 0; border-top: 1px solid var(--line); } }

/* -- 7. Editorial letter ------------------------------------------ */
.letter { max-width: 62ch; margin: 0 auto; }
.letter-open {
  font-family: var(--font-d); font-weight: 400; font-variation-settings: "opsz" 40;
  font-size: var(--t-h3); line-height: 1.45; color: var(--text); margin-bottom: var(--sp-s);
  letter-spacing: -0.005em;
}
.letter > p:not(.letter-open) { font-size: var(--t-body); font-weight: 300; line-height: 1.85; color: var(--text-dim); margin-bottom: var(--sp-s); }
.letter-sign { margin-top: var(--sp-l); padding-top: var(--sp-s); border-top: 1px solid var(--line-soft); }
.letter-sign b { display: block; font-family: var(--font-d); font-size: var(--t-lead); font-weight: 400; color: var(--text); }
.letter-sign span { font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold); }

/* -- 8. Booking band + form ---------------------------------------
   A raised, gold-edged surface rather than a colour change, because
   the page is already dark and a second dark is not a moment. */
.band {
  background-color: var(--surface-2);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: var(--sp-2xl) 0;
}
.band-grid { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: var(--sp-xl); align-items: start; }
.band-points { list-style: none; display: grid; gap: var(--sp-xs); margin-top: var(--sp-m); }
.band-points li { display: flex; gap: var(--sp-2xs); align-items: flex-start; font-size: var(--t-small); line-height: 1.65; color: var(--text-dim); }
.band-points i { color: var(--gold); font-size: 1.2rem; flex-shrink: 0; margin-top: 0.05em; }

.form-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: var(--sp-m);
  box-shadow: var(--shadow-lg);
}
.fgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); gap: var(--sp-s); }
.field { display: grid; gap: var(--sp-3xs); }
.field-full { grid-column: 1 / -1; }
.field label {
  font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--text);
}
.field input, .field select, .field textarea {
  /* 16px is a hard floor, not a preference: iOS Safari zooms the whole
     page in when a focused control is smaller, and does not zoom back
     out. --t-small tops out at 15.2px, so every field on the site would
     do it, on the one form the site exists to collect. max() holds the
     floor at every width without a breakpoint. */
  width: 100%; font-family: var(--font-b); font-size: max(16px, var(--t-small));
  padding: var(--sp-2xs) var(--sp-xs);
  border-radius: var(--r);
  background: var(--field-bg);
  border: 1px solid var(--field-line);
  color: var(--text);
  transition: border-color 0.3s, background 0.3s, box-shadow 0.3s;
}
.field textarea { resize: vertical; min-height: 92px; }
.field input::placeholder, .field textarea::placeholder { color: var(--placeholder); }
.field select option { background: var(--surface); color: var(--text); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--gold); background: var(--surface);
  box-shadow: 0 0 0 3px var(--gold-dim);
}
.field-help { font-size: var(--t-micro); line-height: 1.6; color: var(--text-dim); }
.field-err { font-size: var(--t-micro); color: var(--err); min-height: 1em; }
.field.has-err input, .field.has-err select { border-color: var(--err); }
.form-card > form > .btn { width: 100%; margin-top: var(--sp-m); }
.form-note { margin-top: var(--sp-xs); font-size: var(--t-micro); line-height: 1.6; color: var(--text-dim); text-align: center; }

/* form result states */
.form-state { display: none; text-align: center; padding: var(--sp-s) 0; }
.form-state.is-on { display: block; }
.form-state i { font-size: 2.6rem; color: var(--gold); display: block; margin-bottom: var(--sp-s); }
.form-state h3 { font-family: var(--font-d); font-weight: 400; font-size: var(--t-h3); color: var(--text); margin-bottom: var(--sp-2xs); }
.form-state p { font-size: var(--t-small); line-height: 1.7; color: var(--text-dim); max-width: 44ch; margin: 0 auto; }
.form-state .btn { display: inline-flex; width: auto; }
.is-busy { opacity: 0.55; pointer-events: none; }

@media (max-width: 900px) { .band-grid { grid-template-columns: 1fr; } }

/* -- Breadcrumbs ---------------------------------------------------
   The site is flat, so this is one level deep and mostly serves the
   BreadcrumbList schema and the back-out affordance. Kept quiet so it
   does not compete with the eyebrow directly beneath it. */
.crumbs {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2xs);
  margin-bottom: var(--sp-s);
  font-family: var(--font-m); font-size: var(--t-micro);
  letter-spacing: 0.14em; text-transform: uppercase;
}
/* the type is deliberately small, but the target it sits in cannot be:
   24px is the WCAG 2.5.8 floor, and this is a thumb on a phone */
.crumbs a { display: inline-flex; align-items: center; min-height: 24px;
            color: var(--text-mut); text-decoration: none; transition: color 0.25s; }
.crumbs a:hover { color: var(--gold-lit); }
.crumbs i { font-size: 0.85em; color: var(--gold); }
.crumbs [aria-current] { color: var(--text-dim); }

/* -- Interior page hero ------------------------------------------- */
.phero { padding: calc(var(--hdr-h) + var(--sp-xl)) 0 var(--sp-l); border-bottom: 1px solid var(--line-soft); }
.phero-grid { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: var(--sp-l); align-items: end; }
.phero h1 {
  font-family: var(--font-d); font-weight: 400; font-variation-settings: "opsz" 72;
  font-size: var(--t-h2); line-height: 1.06; letter-spacing: -0.02em; color: var(--text);
  text-wrap: balance;
}
.phero h1 em { font-style: italic; color: var(--gold-display); line-height: 1.16; padding-bottom: 0.08em; display: inline-block; }
.phero-grid > p { font-size: var(--t-lead); font-weight: 300; line-height: 1.68; color: var(--text-dim); max-width: 44ch; }
@media (max-width: 800px) { .phero-grid { grid-template-columns: 1fr; gap: var(--sp-s); } }

/* -- Product article ---------------------------------------------- */
.prod { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-xl); align-items: center; }
.prod-idx { font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.18em; text-transform: uppercase; color: var(--gold); margin-bottom: var(--sp-xs); }
.prod h2 { font-family: var(--font-d); font-weight: 400; font-size: var(--t-h2); line-height: 1.1; letter-spacing: -0.018em; color: var(--text); margin-bottom: var(--sp-3xs); }
.prod-sub { font-family: var(--font-m); font-size: var(--t-label); letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-mut); margin-bottom: var(--sp-s); }
.prod p.d { font-size: var(--t-body); font-weight: 300; line-height: 1.78; color: var(--text-dim); margin-bottom: var(--sp-m); max-width: 50ch; }
.prod ul { list-style: none; display: grid; gap: var(--sp-2xs); margin-bottom: var(--sp-m); }
.prod li { position: relative; padding-left: var(--sp-s); font-size: var(--t-small); line-height: 1.68; color: var(--text-dim); }
.prod li::before { content: ""; position: absolute; left: 0; top: 0.72em; width: 9px; height: 1px; background: var(--gold); }
.prod-media { position: relative; }
.prod-media .frame {
  border-radius: var(--r); overflow: hidden; position: relative;
  background: var(--plate);
  border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  padding: var(--sp-m);
  min-height: clamp(260px, 28vw, 380px);
  box-shadow: var(--shadow-lg);
}
.prod-media .frame > img { width: 100%; height: 100%; object-fit: cover; position: absolute; inset: 0; }
.prod-media .frame .tint { position: absolute; inset: 0; background: linear-gradient(155deg, rgba(201,149,42,0.14), transparent 44%, rgba(7,30,27,0.5)); }
/* a schematic is read, not cropped */
.prod-media .frame.is-draw > img,
.prod-media .frame.is-draw > svg { position: relative; inset: auto; width: 100%; height: auto; object-fit: contain; z-index: 1; }
/* The drawing frame takes the small inset, the same as the card art
   does. At --sp-m the padding was eating 48px out of a 349px panel on
   a phone: 14 percent of the width of a drawing that has nowhere else
   to grow, since a landscape drawing on a narrow screen is bound by
   width and by nothing else. Photographs keep the larger inset; they
   are cropped to fill and do not care. */
.prod-media .frame.is-draw { padding: var(--sp-2xs); }
/* A portrait drawing cannot take the 100% width above it, or a 460x620
   skid would stand taller than the viewport. Bound it by width rather
   than by height: capping the height starves it on a phone, where the
   frame is wide and the cap leaves it 208px across with sub-pixel
   strokes. This fills the frame until 300px, which holds the linework
   above 1px at every width. */
.prod-media .frame.is-draw.is-tall > img,
.prod-media .frame.is-draw.is-tall > svg { width: clamp(220px, 100%, 300px); height: auto; }
.prod-media .frame.is-draw::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(rgba(201,149,42,0.05) 1px, transparent 1px) 0 0 / 100% 38px,
    linear-gradient(90deg, rgba(201,149,42,0.05) 1px, transparent 1px) 0 0 / 38px 100%;
  mask-image: radial-gradient(72% 72% at 50% 50%, #000, transparent);
  -webkit-mask-image: radial-gradient(72% 72% at 50% 50%, #000, transparent);
}
@media (max-width: 900px) { .prod { grid-template-columns: 1fr; } }

/* -- Spec sheet: grouped chunks, sparse rules --------------------- */
.specs { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr)); gap: var(--sp-s); }
.spec-group {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  padding: var(--sp-m); box-shadow: inset 0 1px 0 var(--inset-hl);
}
.spec-group h4 { font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.18em; text-transform: uppercase; color: var(--gold); margin-bottom: var(--sp-s); }
.spec-group dl { display: grid; gap: var(--sp-xs); }
.spec-group dl > div { display: grid; gap: 0.1em; }
.spec-group dt { font-size: var(--t-micro); color: var(--text-dim); }
.spec-group dd { font-family: var(--font-m); font-size: var(--t-small); color: var(--text); }
.spec-group dd small { font-size: 0.78em; color: var(--text-dim); }

/* -- Inline key/value pairs (inside a product cell) --------------- */
.kv {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(130px, 100%), 1fr)); gap: var(--sp-xs) var(--sp-s);
  margin: 0 0 var(--sp-m); padding-top: var(--sp-s); border-top: 1px solid var(--line-soft);
}
.kv > div { display: grid; gap: 0.1em; }
.kv dt { font-size: var(--t-micro); color: var(--text-dim); }
.kv dd { font-family: var(--font-m); font-size: var(--t-small); color: var(--text); }
.kv dd small { font-size: 0.78em; color: var(--text-dim); }

/* -- Rental terms: definition grid -------------------------------- */
.terms {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr));
  gap: 1px; background: var(--line-soft);
  border: 1px solid var(--line); border-radius: var(--r); overflow: hidden;
}
.terms > div { background: var(--surface); padding: var(--sp-m); display: grid; gap: var(--sp-3xs); align-content: start; }
.terms dt { font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.18em; text-transform: uppercase; color: var(--gold); }
.terms dd { font-size: var(--t-small); line-height: 1.65; color: var(--text); }
.tbd { color: var(--text-dim); font-style: italic; }

/* -- FAQ (native disclosure) -------------------------------------- */
.faq { max-width: 800px; }
.faq details { border-bottom: 1px solid var(--line-soft); }
.faq summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-s);
  padding: var(--sp-s) 0;
  font-size: var(--t-body); font-weight: 400; color: var(--text);
  transition: color 0.3s;
}
.faq summary:hover { color: var(--gold-lit); }
.faq summary::-webkit-details-marker { display: none; }
.faq summary i { color: var(--gold); font-size: 1.2rem; flex-shrink: 0; transition: transform 0.4s var(--ease); }
.faq details[open] summary i { transform: rotate(45deg); }
.faq .ans { padding: 0 0 var(--sp-s); font-size: var(--t-small); line-height: 1.8; color: var(--text-dim); max-width: 66ch; }

/* -- Contact detail rows ------------------------------------------ */
.contact-grid { display: grid; grid-template-columns: 0.85fr 1.15fr; gap: var(--sp-xl); align-items: start; }
.cinfo { list-style: none; display: grid; gap: var(--sp-m); }
.cinfo li { display: grid; grid-template-columns: clamp(32px, 3vw, 40px) 1fr; gap: var(--sp-xs); align-items: start; }
.cinfo i { font-size: 1.35rem; color: var(--gold); }
.cinfo b { display: block; font-size: var(--t-body); font-weight: 500; color: var(--text); margin-bottom: 0.15em; }
.cinfo span, .cinfo a { font-size: var(--t-small); line-height: 1.65; color: var(--text-dim); text-decoration: none; }
.cinfo a:hover { color: var(--gold-lit); }
@media (max-width: 880px) { .contact-grid { grid-template-columns: 1fr; } }

/* -- Value tiles --------------------------------------------------- */
.tiles { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--sp-s); }
.tile {
  border: 1px solid var(--line); border-radius: var(--r); padding: var(--sp-m);
  background: var(--surface); box-shadow: inset 0 1px 0 var(--inset-hl);
  transition: border-color 0.4s var(--ease-2);
}
.tile:hover { border-color: var(--gold-dim); }
.tile-lg { grid-column: span 7; }
.tile-sm { grid-column: span 5; }
.tile-half { grid-column: span 6; }
/* the one tile that carries the accent, so the grid has a focal point */
.tile-dark {
  background-color: var(--ink-3);
  background-image: radial-gradient(80% 120% at 100% 0%, rgba(201,149,42,0.13), transparent 62%);
  border-color: rgba(201,149,42,0.28);
}
.tile i { font-size: 1.6rem; color: var(--gold); display: block; margin-bottom: var(--sp-s); }
.tile h3 { font-family: var(--font-d); font-weight: 400; font-size: var(--t-h3); line-height: 1.2; letter-spacing: -0.01em; color: var(--text); margin-bottom: var(--sp-2xs); }
.tile p { font-size: var(--t-small); line-height: 1.72; color: var(--text-dim); }
@media (max-width: 880px) { .tile-lg, .tile-sm, .tile-half { grid-column: span 12; } }

/* -- Section head (stacked, never split left/right) --------------- */
.shead { max-width: 620px; margin-bottom: var(--sp-l); }
.shead .lead { margin-top: var(--sp-xs); }

/* -- Technical drawings -------------------------------------------
   Both are inked gold on the ink-2 plate, so the two drawings match
   and the softener's own #0B2724 masking fills land exactly on the
   plate. Sizing is handled by .cell-art.is-draw and .prod-media
   .frame.is-draw; the drawings carry no rules of their own. */

/* The honeypot. Off-screen rather than display:none, because a bot that
   skips hidden inputs will still fill this one; aria-hidden and
   tabindex=-1 on the wrapper keep it away from real people. Never give
   this a name a password manager would recognise. */
.hp {
  position: absolute; left: -9999px; top: auto;
  width: 1px; height: 1px; overflow: hidden;
}



/* -- Legal documents ----------------------------------------------
   Privacy, terms and disclaimer. These are read once, and usually not
   from the top: somebody arrives looking for one clause. So the page
   is built to be scanned - numbered sections, each one an anchor, a
   contents list at the top, and a measure narrow enough that the eye
   finds the next line without hunting.

   Nothing here is used by any other page, and no existing rule is
   touched. The type comes from the same fluid scale as everything
   else, so these pages resize with the rest of the site. */
.legal { max-width: 72ch; }
/* the legal sections are covered by the global [id] rule in kyna.css */
.legal > section + section {
  margin-top: var(--sp-l); padding-top: var(--sp-m);
  border-top: 1px solid var(--line-soft);
}
.legal h2 {
  font-family: var(--font-d); font-weight: 400; font-variation-settings: "opsz" 40;
  font-size: var(--t-h3); line-height: 1.3; letter-spacing: -0.008em;
  color: var(--text); margin-bottom: var(--sp-xs);
}
.legal h3 {
  font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--gold);
  margin-top: var(--sp-m); margin-bottom: var(--sp-2xs);
}
.legal p, .legal li {
  font-size: var(--t-small); line-height: 1.8; font-weight: 300; color: var(--text-dim);
}
.legal p { margin-bottom: var(--sp-s); }
.legal p:last-child, .legal ul:last-child, .legal ol:last-child { margin-bottom: 0; }
.legal ul, .legal ol { margin: 0 0 var(--sp-s) var(--sp-s); padding-left: var(--sp-xs); }
.legal li { margin-bottom: var(--sp-2xs); }
.legal li::marker { color: var(--gold); }
.legal strong { color: var(--text); font-weight: 500; }
.legal a { color: var(--gold-lit); text-underline-offset: 0.2em; }
.legal a:hover, .legal a:focus-visible { color: var(--text); }

/* The stamp under the title. Dates matter on these pages: a policy
   with no date is a policy nobody can tell is current. */
.legal-stamp {
  font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--text-mut);
  margin-bottom: var(--sp-l); padding-bottom: var(--sp-s);
  border-bottom: 1px solid var(--line-soft);
  display: flex; flex-wrap: wrap; gap: var(--sp-2xs) var(--sp-m);
}

/* Contents. A plain list of links, because a long document that cannot
   be jumped into gets closed. */
.legal-toc { margin-bottom: var(--sp-l); }
.legal-toc ol {
  margin: 0; padding: 0; list-style: none;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: var(--sp-3xs) var(--sp-m);
  counter-reset: toc;
}
.legal-toc li { margin: 0; counter-increment: toc; }
.legal-toc a {
  display: flex; gap: var(--sp-2xs); align-items: baseline;
  min-height: 24px; color: var(--text-dim); text-decoration: none;
  font-size: var(--t-small); line-height: 1.6;
}
.legal-toc a::before {
  content: counter(toc, decimal-leading-zero);
  font-family: var(--font-m); font-size: var(--t-micro); color: var(--gold);
  letter-spacing: 0.08em; flex: none;
}
.legal-toc a:hover, .legal-toc a:focus-visible { color: var(--text); }

/* A box for the one or two things on each page that must not be
   skimmed past. Raised rather than coloured, so it reads as emphasis
   and not as an error. */
.legal-note {
  margin: var(--sp-m) 0; padding: var(--sp-s) var(--sp-m);
  background: var(--surface); border: 1px solid var(--line);
  border-left: 2px solid var(--gold-fill); border-radius: var(--r);
}
.legal-note p:last-child { margin-bottom: 0; }

/* Definition pairs, used for the contact block. */
.legal dl { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-3xs) var(--sp-s); margin: 0; }
.legal dt {
  font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--gold); padding-top: 0.35em;
}
.legal dd { margin: 0; font-size: var(--t-small); line-height: 1.8; font-weight: 300; color: var(--text-dim); }

/* Footer legal strip: the three documents live here on every page. */
.ftr-legal-links { display: flex; flex-wrap: wrap; gap: var(--sp-3xs) var(--sp-s); }
.ftr-legal-links a {
  display: inline-flex; align-items: center; min-height: 24px;
  color: inherit; text-decoration: none;
}
.ftr-legal-links a:hover, .ftr-legal-links a:focus-visible { color: var(--gold); }

/* -- Consent bar --------------------------------------------------
   Shown only when KYNA_CONFIG.ga holds a real measurement id, and only
   until the visitor has answered once. Built in JavaScript rather than
   sitting in the markup, so that a visitor who has already answered
   never downloads it, and so a visitor with JavaScript off is never
   asked about a tracker that cannot load without JavaScript anyway.

   It borrows the footer's dark token set, so it reads as part of the
   site rather than as something bolted on by a vendor. */
.consent {
  position: fixed; z-index: var(--z-float);
  left: var(--gutter); right: var(--gutter); bottom: var(--gutter);
  max-width: 640px;
  --bg:        var(--ink);
  --surface:   var(--ink-2);
  --text:      #F4EFE4;
  --text-dim:  rgba(244,239,228,0.66);
  --line:      rgba(244,239,228,0.14);
  /* The golds have to come across too. Without these the bar
     inherits the light ground's deep gold, which measures 2.12:1
     against this dark panel and fails AA outright. These are the
     same values the footer uses: 9.1:1 and 6.3:1 on ink. */
  --gold-lit:  #E0B457;
  --gold:      #C9952A;
  background: var(--ink-2); color: var(--text);
  border: 1px solid var(--line);
  border-left: 2px solid var(--gold-fill);
  border-radius: var(--r);
  box-shadow: var(--shadow-lg);
  padding: var(--sp-s) var(--sp-m);
}
.consent:focus-visible { outline: 2px solid var(--gold-lit); outline-offset: 3px; }
.consent-title {
  font-family: var(--font-d); font-weight: 400; font-variation-settings: "opsz" 20;
  font-size: var(--t-lead); line-height: 1.3; color: var(--text);
  margin-bottom: var(--sp-3xs);
}
.consent p:not(.consent-title) {
  font-size: var(--t-small); line-height: 1.65; font-weight: 300;
  color: var(--text-dim); margin-bottom: var(--sp-s);
}
.consent a { color: var(--gold-lit); text-underline-offset: 0.2em; }
.consent a:hover, .consent a:focus-visible { color: var(--text); }
.consent-row { display: flex; flex-wrap: wrap; gap: var(--sp-2xs) var(--sp-xs); }
.consent-row .btn { flex: 1 1 auto; justify-content: center; }

/* While the bar is up it would sit under the floating chat button, so
   the button steps aside rather than the bar shrinking to avoid it. */
body.has-consent-bar .wa { display: none; }

/* Below the width where the bar spans the screen, the two buttons stack
   only if they genuinely will not fit; flex-wrap already handles it, so
   this changes structure and not size, as everything else here does. */
@media (max-width: 420px) {
  .consent-row .btn { flex: 1 1 100%; }
}

/* -- Hero figure, drawing variant ---------------------------------
   The hero column stood empty for a long time because the honest
   options were a photograph nobody has or stock imagery of somebody
   else's plant. The third option was in the repo all along: the RO
   skid drawing is the most distinctive thing KYNA owns, so it leads.

   The frame keeps the plate ground, and that is not decoration. The
   drawing masks its own overlaps with fill="#0B2724", the plate token,
   so on any other ground those fills would show as pale rectangles
   where pipes cross vessels. Plate ground, or re-ink the SVG. */
.hero-fig .frame.is-draw {
  aspect-ratio: auto;
  padding: var(--sp-s);
  display: grid; place-items: center;
  border-color: var(--line-soft);
  box-shadow: none;
}
.hero-fig .frame.is-draw > svg { display: block; width: 100%; height: auto; }

/* The warm wash on .frame was written for cool-lit photography. Over
   gold linework it only greys the gold, so here it becomes a light
   from above instead, which lifts the top of the machine and lets the
   skid sit into the dark. */
.hero-fig .frame.is-draw::after {
  background: radial-gradient(120% 85% at 50% 0%, rgba(201,149,42,0.10), transparent 62%);
}

/* Same drafting grid the product cards use, so the hero drawing and
   the card drawings read as the same surface. */
.hero-fig .frame.is-draw::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background:
    linear-gradient(rgba(201,149,42,0.05) 1px, transparent 1px) 0 0 / 100% 38px,
    linear-gradient(90deg, rgba(201,149,42,0.05) 1px, transparent 1px) 0 0 / 38px 100%;
  mask-image: radial-gradient(72% 72% at 50% 50%, #000, transparent);
  -webkit-mask-image: radial-gradient(72% 72% at 50% 50%, #000, transparent);
}
.hero-fig .frame.is-draw > svg { position: relative; z-index: 1; }

/* Stacked, the drawing follows the CTA rather than pushing it down, and
   it is bound by width so a landscape drawing on a narrow screen does
   not turn into a letterbox. Structure only: no size token is changed
   here, the clamp scale still owns every dimension. */
@media (max-width: 900px) {
  .hero-fig .frame.is-draw { aspect-ratio: auto; padding: var(--sp-xs); }
  .hero-fig .frame.is-draw > svg { width: clamp(260px, 100%, 520px); margin: 0 auto; }
}

/* -- Staged enquiry form ------------------------------------------
   Three questions instead of one screen of eight fields. The fields
   themselves are unchanged and still use .field, .fgrid and
   .field-err; what is here is only the pacing: the step markers, the
   big tappable answers, and the back/continue row. */

/* Step markers. Three, because the follow-up question after the first
   answer belongs to step one rather than being a step of its own: a
   progress bar that grows an extra segment depending on your answer
   reads as a penalty for choosing. */
.fsteps { display: flex; gap: var(--sp-3xs); margin-bottom: var(--sp-2xs); }
.fstep {
  height: 2px; flex: 1 1 0; border-radius: 2px;
  background: var(--line);
  transition: background 0.4s var(--ease);
}
.fstep.is-on { background: var(--gold-fill); }
.fcount {
  font-family: var(--font-m); font-size: var(--t-micro); letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--text-mut); margin-bottom: var(--sp-s);
}

.fstage-q {
  font-family: var(--font-d); font-weight: 400; font-variation-settings: "opsz" 40;
  font-size: var(--t-h3); line-height: 1.25; letter-spacing: -0.008em;
  color: var(--text); margin-bottom: var(--sp-s);
}
.fstage-q:focus-visible { outline: 2px solid var(--gold-lit); outline-offset: 6px; }

/* The answers. Full-width rows rather than a row of small pills,
   because on a phone this is the whole interaction and a big target
   that says what it does beats a neat grid of guesses. */
.choices { display: grid; gap: var(--sp-2xs); }
.choice {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-xs);
  width: 100%; min-height: 52px;
  padding: var(--sp-xs) var(--sp-s);
  text-align: left;
  font-family: var(--font-b); font-size: var(--t-small); font-weight: 400;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r);
  cursor: pointer;
  transition: border-color 0.25s var(--ease), background 0.25s var(--ease),
              transform 0.25s var(--ease);
}
/* The chevron is drawn here rather than pulled from the icon sheet,
   because it is a caret two lines long and adding a glyph for it would
   put a whole extra rule in icons.css for one arrow. */
.choice::after {
  content: ""; flex: none; width: 7px; height: 7px;
  border-right: 1.5px solid var(--gold); border-bottom: 1.5px solid var(--gold);
  transform: rotate(-45deg); margin-right: 2px;
  transition: transform 0.25s var(--ease);
}
.choice:hover, .choice:focus-visible {
  border-color: var(--gold-fill);
  background: var(--surface);
}
.choice:hover::after, .choice:focus-visible::after { transform: rotate(-45deg) translate(2px, 2px); }
.choice:active { transform: scale(0.995); }

/* Back and continue. Back is quiet and on the left, because it is the
   escape hatch and not the thing to press. */
.fnav {
  display: flex; align-items: center; gap: var(--sp-xs);
  margin-top: var(--sp-m); flex-wrap: wrap;
}
.fnav [data-back] { margin-right: auto; }
.fstage[data-stage="who"] .fnav { margin-top: var(--sp-s); }

@media (prefers-reduced-motion: reduce) {
  .fstep, .choice, .choice::after { transition: none; }
}
