/* ==========================================================================
   STUDIO — pages/about.css
   Sections that belong to about.html only. Everything reusable (buttons,
   labels, panels, notes, stat, phead, band, rule) comes from the kit.

   House rules obeyed: no gradients, hairlines instead of shadows, radii
   capped at 12px, motion 150–220ms ease-out, logical properties only.
   ========================================================================== */

/* ==========================================================================
   1. THE FLOOR — a ruled triptych straight under the page header.
   Three photographs, flush, sharing one hairline. The photos are the only
   colour on the page until the red spine of the process timeline.
   ========================================================================== */
.floor {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  border-radius: var(--r-lg);
  overflow: hidden;
}
@media (min-width: 700px) {
  .floor { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.floor__cell {
  display: grid;
  gap: var(--sp-4);
  padding: var(--sp-5);
  background: var(--bg);
  box-shadow: 0 0 0 1px var(--border);
  transition: background-color var(--dur-2) var(--ease);
}
.floor__cell:hover { background: var(--bg-hover); }

.floor__media {
  aspect-ratio: 4 / 3;
  border: var(--border-1);
  border-radius: var(--r-md);
  background: var(--bg-surface);
  overflow: hidden;
}
.floor__img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  /* the house crop: the client's photos carry burned-in furniture in the
     bottom of the frame, so the crop budget is spent there. */
  transform: scale(1.16);
  transform-origin: center 32%;
  transition: transform var(--dur-4) var(--ease);
}
.floor__cell:hover .floor__img { transform: scale(1.21); }

.floor__cap {
  display: grid;
  gap: var(--sp-1);
  min-inline-size: 0;
}
.floor__name {
  font-size: var(--fs-h4);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-head);
  color: var(--text);
}
.floor__text {
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--text-muted);
}

/* ==========================================================================
   2. STORY — the editorial column plus a quiet fact plate.
   ========================================================================== */
.story {
  display: grid;
  gap: var(--sp-9);
  align-items: start;
}
@media (min-width: 960px) {
  .story {
    grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
    column-gap: var(--sp-12);
  }
}

.story__lead { display: grid; gap: var(--sp-5); min-inline-size: 0; }
.story__title { font-size: var(--fs-h2); max-inline-size: 20ch; }

/* the three paragraphs from SITE_DATA.about.story_* */
.story__prose {
  font-size: var(--fs-lead);
  line-height: var(--lh-relaxed);
  color: var(--text-secondary);
  max-inline-size: 62ch;
  border-block-start: var(--border-1);
  padding-block-start: var(--sp-6);
}
.story__prose p + p { margin-block-start: var(--sp-5); }
/* the opening line is set in the ink — an editorial drop-in, not a gradient */
.story__prose p:first-child { color: var(--text); }

.story__aside { display: grid; gap: var(--sp-6); min-inline-size: 0; }
@media (min-width: 960px) {
  .story__aside { position: sticky; inset-block-start: calc(var(--header-h) + var(--sp-8)); }
}

.story__fig { display: grid; gap: var(--sp-3); margin: 0; }
.story__frame {
  aspect-ratio: 4 / 5;
  border: var(--border-1);
  border-radius: var(--r-lg);
  background: var(--bg-surface);
  overflow: hidden;
}
.story__img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  /* a 1:1 source in a 4:5 frame already crops the sides, so this only needs
     the small bias that pushes the burned-in strip off the bottom. */
  transform: scale(1.05);
  transform-origin: center 38%;
}
.story__figcap {
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  color: var(--text-muted);
}

/* the at-a-glance plate */
.facts {
  display: grid;
  border-block-start: var(--border-1);
}
.fact {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-block: var(--sp-4);
  border-block-end: var(--border-1);
  font-size: var(--fs-sm);
}
.fact__k { color: var(--text-muted); }
.fact__v {
  color: var(--text);
  font-weight: var(--fw-semibold);
  text-align: end;
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   3. STATS BAND — app.js fills #proofGrid. The FOUNDED value carries
   data-raw, so 2005 is painted whole and never ticks up through 1893.
   ========================================================================== */
.proof {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0;
  border-radius: var(--r-lg);
  overflow: hidden;
}
@media (min-width: 860px) {
  .proof { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.proof__item {
  display: grid;
  gap: var(--sp-3);
  padding: var(--sp-8) var(--sp-6);
  background: var(--bg);
  box-shadow: 0 0 0 1px var(--border);
}

/* ==========================================================================
   4. CAPABILITIES — six ruled cells. Rings collapse into one shared
   hairline, exactly like .cards.
   ========================================================================== */
.abcaps {
  display: grid;
  /* six items: EXPLICIT column counts, so a row is never left half-ruled.
     auto-fill would give four columns at 1440 and strand two cells. */
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  border-radius: var(--r-lg);
  overflow: hidden;
}
@media (min-width: 660px) {
  .abcaps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1020px) {
  .abcaps { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.abcap {
  display: grid;
  gap: var(--sp-3);
  align-content: start;
  padding: var(--sp-7) var(--sp-6);
  background: var(--bg);
  box-shadow: 0 0 0 1px var(--border);
  transition: background-color var(--dur-2) var(--ease),
              box-shadow var(--dur-2) var(--ease);
}
.abcap:hover {
  background: var(--bg-hover);
  box-shadow: 0 0 0 1px var(--border-strong);
  z-index: 1;
}
.abcap__n {
  font-size: var(--fs-label);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-label);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  transition: color var(--dur-2) var(--ease);
}
.abcap:hover .abcap__n { color: var(--text-accent); }
[dir="rtl"] .abcap__n { letter-spacing: 0; }
.abcap__title {
  font-size: var(--fs-h4);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-head);
  color: var(--text);
}
.abcap__desc {
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--text-muted);
}

/* ==========================================================================
   5. PROCESS — the numbered timeline. THE set-piece of this page.
   A hairline spine with a square node per step. As a step scrolls into
   view its node fills with ink and the spine BELOW it turns brand red, so
   the route paints itself in order, top to bottom. Colour: one flat red,
   doing real work. No gradient, no bounce.
   ========================================================================== */
.route {
  display: grid;
  gap: var(--sp-9);
  align-items: start;
}
@media (min-width: 980px) {
  .route {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
    column-gap: var(--sp-12);
  }
}
.route__lead {
  display: grid;
  gap: var(--sp-5);
  align-content: start;
  justify-items: start;
  min-inline-size: 0;
}
@media (min-width: 980px) {
  .route__lead { position: sticky; inset-block-start: calc(var(--header-h) + var(--sp-8)); }
}
.route__title { font-size: var(--fs-h2); max-inline-size: 14ch; }
.route__text {
  font-size: var(--fs-sm);
  line-height: var(--lh-relaxed);
  color: var(--text-muted);
  max-inline-size: 44ch;
}
/* justify-items:start would otherwise size the callout to its content */
.route__lead > .note {
  inline-size: 100%;
  max-inline-size: 48ch;
  /* The kit's .note plates itself in --bg-surface, but this one sits ON a
     .band--surface — same value, so the callout dissolved into the band in
     BOTH modes. It takes the page ground instead, exactly like the ruled
     cells (.abcap, .vow, .proof__item) do on their bands. */
  background: var(--bg);
}

/* --- the spine --------------------------------------------------------- */
.tl {
  display: grid;
  list-style: none;
  min-inline-size: 0;

  /* The lit node is the INVERSE of the page, not a fixed dark square.
     In the light that is the ink plate with white numerals. In the dark the
     ink (#08090C) sits a hair BELOW the page ground, so an "inked" node was
     indistinguishable from an unlit one — the whole gesture died. At night it
     therefore inverts the other way: a light plate with dark numerals. Same
     idea (the step flips to the opposite of the page), same hairline geometry,
     no glow. */
  --tl-node-on-bg: var(--bg-ink);
  --tl-node-on-bd: var(--bg-ink);
  --tl-node-on-fg: var(--text-on-ink);
}
:root[data-theme="dark"] .tl {
  --tl-node-on-bg: var(--text);
  --tl-node-on-bd: var(--text);
  --tl-node-on-fg: var(--bg);
}
/* no-JS fallback — mirrors the boot script's default (see tokens.css) */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .tl {
    --tl-node-on-bg: var(--text);
    --tl-node-on-bd: var(--text);
    --tl-node-on-fg: var(--bg);
  }
}

.tl__step {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  column-gap: var(--sp-5);
  padding-block-end: var(--sp-8);
  min-inline-size: 0;
}
.tl__step:last-child { padding-block-end: 0; }

.tl__rail { position: relative; display: flex; justify-content: center; }
/* the connector to the NEXT node — it has to cross the step's bottom
   padding, hence the negative logical inset. */
.tl__rail::before {
  content: "";
  position: absolute;
  inset-block-start: 44px;
  inset-block-end: calc(var(--sp-8) * -1);
  inset-inline-start: calc(50% - 1px);
  inline-size: 2px;
  background: var(--border);
  transition: background-color var(--dur-3) var(--ease);
}
.tl__step:last-child .tl__rail::before { display: none; }
/* the spine fills behind you as each step arrives */
.tl__step.is-lit .tl__rail::before { background: var(--accent); }

.tl__n {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  flex: none;
  border: var(--border-1);
  border-radius: var(--r);
  background: var(--bg);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  transition: background-color var(--dur-3) var(--ease),
              border-color var(--dur-3) var(--ease),
              color var(--dur-3) var(--ease);
}
.tl__step.is-lit .tl__n {
  background: var(--tl-node-on-bg);
  border-color: var(--tl-node-on-bd);
  color: var(--tl-node-on-fg);
}

.tl__body {
  display: grid;
  gap: var(--sp-2);
  align-content: start;
  padding-block-start: 9px;   /* optically level with the node's numeral */
  min-inline-size: 0;
}
.tl__title {
  font-size: var(--fs-h4);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-head);
  color: var(--text);
}
.tl__desc {
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--text-muted);
  max-inline-size: 58ch;
}

@media (max-width: 420px) {
  .tl__step { grid-template-columns: 40px minmax(0, 1fr); column-gap: var(--sp-4); }
  .tl__n { inline-size: 40px; block-size: 40px; }
  .tl__rail::before { inset-block-start: 40px; }
}

/* ==========================================================================
   6. QUALITY — the checklist and the three promises.
   ========================================================================== */
.qual {
  display: grid;
  gap: var(--sp-9);
  align-items: start;
}
@media (min-width: 960px) {
  .qual {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    column-gap: var(--sp-11);
  }
}
.qual__lead { display: grid; gap: var(--sp-5); min-inline-size: 0; }
.qual__title { font-size: var(--fs-h2); max-inline-size: 16ch; }
.qual__text {
  font-size: var(--fs-sm);
  line-height: var(--lh-relaxed);
  color: var(--text-muted);
  max-inline-size: 54ch;
}

.checks {
  display: grid;
  list-style: none;
  border-block-start: var(--border-1);
  margin-block-start: var(--sp-2);
}
.check-row {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  align-items: start;
  column-gap: var(--sp-4);
  padding-block: var(--sp-4);
  border-block-end: var(--border-1);
  font-size: var(--fs-sm);
  color: var(--text-secondary);
}
.check-row svg {
  inline-size: 18px;
  block-size: 18px;
  margin-block-start: 3px;
  color: var(--accent);
  flex: none;
}
.check-row strong { color: var(--text); font-weight: var(--fw-semibold); }

.qual__aside { display: grid; gap: var(--sp-5); min-inline-size: 0; }
.qual__frame {
  aspect-ratio: 1 / 1;
  border: var(--border-1);
  border-radius: var(--r-lg);
  background: var(--bg-surface);
  overflow: hidden;
}
.qual__img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transform: scale(1.1);
  transform-origin: center 34%;
}

/* the three promises — ruled cells again */
.vows {
  display: grid;
  grid-template-columns: minmax(0, 1fr);   /* three items — three columns, or one */
  gap: 0;
  border-radius: var(--r-lg);
  overflow: hidden;
  margin-block-start: var(--sp-10);
}
@media (min-width: 880px) {
  .vows { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.vow {
  display: grid;
  gap: var(--sp-3);
  align-content: start;
  padding: var(--sp-7) var(--sp-6);
  background: var(--bg);
  box-shadow: 0 0 0 1px var(--border);
  transition: background-color var(--dur-2) var(--ease);
}
.vow:hover { background: var(--bg-hover); }
.vow__ico {
  display: grid;
  place-items: center;
  inline-size: 36px;
  block-size: 36px;
  border: var(--border-1);
  border-radius: var(--r);
  background: var(--bg-surface);
  color: var(--text-accent);
}
.vow__ico svg { inline-size: 18px; block-size: 18px; }
.vow__title {
  font-size: var(--fs-h4);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-head);
  color: var(--text);
}
.vow__desc {
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--text-muted);
}

/* ==========================================================================
   7. CLOSING CTA — the page's one dark moment.
   ========================================================================== */
.abcta {
  display: grid;
  gap: var(--sp-8);
  align-items: center;
}
@media (min-width: 900px) {
  .abcta {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    column-gap: var(--sp-11);
  }
}
.abcta__title { font-size: var(--fs-h2); max-inline-size: 18ch; }
.abcta__lead {
  margin-block-start: var(--sp-5);
  font-size: var(--fs-sm);
  line-height: var(--lh-relaxed);
  color: var(--text-on-ink-mut);
  max-inline-size: 52ch;
}
.abcta__panel { display: grid; gap: var(--sp-5); justify-items: start; }
@media (min-width: 900px) {
  .abcta__panel { justify-items: end; }
}
.abcta__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.abcta__note {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  font-size: var(--fs-sm);
  color: var(--text-on-ink-mut);
}
.abcta__note svg { inline-size: 16px; block-size: 16px; flex: none; }
.abcta__note a { color: var(--text-on-ink); font-weight: var(--fw-semibold); }
/* --on-ink-hover, not --c-white: the raw palette value is a LIGHT-mode literal
   and would not have followed the dark token set. */
.abcta__note a:hover { color: var(--on-ink-hover); text-decoration: underline; text-underline-offset: 3px; }
