/* ==========================================================================
   BookPrint.in — design system
   Palette derived from the logo: outlined blue wordmark + green book swoosh.
   Replaces Foundation 5 (229KB) for the client-facing frontend.
   ========================================================================== */

:root {
  /* Brand — from the logo, defined in oklch so tints stay harmonious */
  --blue:        oklch(0.52 0.135 249);
  --blue-deep:   oklch(0.38 0.105 249);
  --blue-tint:   oklch(0.96 0.020 249);
  --green:       oklch(0.73 0.165 139);
  /* Darkened from 0.58/0.140: .eyebrow sets it at 12px/700, which is not "large"
     by WCAG, so it needs 4.5:1 on --paper and was managing 3.97. Now 4.90. */
  --green-deep:  oklch(0.53 0.135 139);
  --green-tint:  oklch(0.96 0.032 139);
  /* Focus indicator. --green reads 2.21:1 on --paper, short of the 3:1 that
     WCAG 1.4.11 asks of a focus ring. Same hue, darkened to 3.36:1. Kept as its
     own token so the decorative green — rules, stat borders — stays bright. */
  --focus:       oklch(0.62 0.160 139);

  /* Paper & ink — warm, not the template's cold #fff */
  --paper:       oklch(0.992 0.0035 249);
  --paper-2:     oklch(0.973 0.006 249);
  --ink:         oklch(0.22 0.014 250);
  --ink-2:       oklch(0.44 0.012 250);
  /* Darkened from 0.60: every use is small text (0.70–0.88rem), so 4.5:1 applies
     and it was managing 3.85 on --paper, 3.65 on --paper-2. Now 4.94 / 4.68. */
  --ink-3:       oklch(0.54 0.010 250);
  --rule:        oklch(0.90 0.006 250);
  /* Same hue as --rule, dark enough for a control boundary. A decorative divider
     is exempt from WCAG 1.4.11; the edge that tells you where an input is is not,
     and --rule gave it 1.32:1. Use this for form controls, --rule for hairlines. */
  --rule-strong: oklch(0.62 0.010 250);

  /* Ink for the dark grounds — the proof band and the footer, both on --ink.
     The same three-step idea as --ink/-2/-3, inverted. Measured on --ink:
     12.45, 9.92 and 5.57. --dark-rule is a hairline, so non-text. */
  --dark-ink:    oklch(0.89 0.010 250);
  --dark-ink-2:  oklch(0.82 0.010 250);
  --dark-ink-3:  oklch(0.66 0.011 250);
  --dark-rule:   oklch(0.32 0.012 250);

  /* The footer ground. It was --ink, a near-black; it is now a deep brand navy.

     --blue-deep was the obvious choice and is wrong: .cta uses --blue-deep, and
     a rounded blue card sitting directly above a full-bleed blue footer reads
     as one undivided block. This is two steps darker, which separates the two
     at 1.60:1 while staying unmistakably the same blue.

     Measured on --foot-bg (#002341): --dark-ink 11.51, --dark-ink-2 9.17,
     --foot-ink-3 7.45, --foot-link 7.59. The first two are reused from the
     dark-ground trio above; --dark-ink-3 is dropped here only because the
     footer wants a slightly brighter label than the proof band does.
     --foot-rule is a decorative hairline at 1.90, which 1.4.11 exempts. */
  --foot-bg:     oklch(0.25 0.070 249);
  --foot-ink-3:  oklch(0.76 0.011 250);
  --foot-link:   oklch(0.75 0.165 139);
  --foot-rule:   oklch(0.42 0.055 249);

  /* Type
     Literata for headings: a serif drawn specifically for reading on screen —
     sturdier stems and a larger x-height than a display face like Caslon,
     which went thin and fragile at these sizes.
     Source Sans 3 for body: humanist, open apertures, holds up at small sizes. */
  --display: "Literata", Georgia, "Times New Roman", serif;
  --body: "Source Sans 3", "Lato", -apple-system, "Segoe UI", Arial, sans-serif;

  /* Fluid scale — clamp() so it breathes without breakpoints */
  --t-hero: clamp(2.35rem, 1.15rem + 4.6vw, 4.6rem);
  --t-h2:   clamp(1.75rem, 1.05rem + 2.5vw, 2.85rem);
  --t-h3:   clamp(1.15rem, 0.95rem + 0.7vw, 1.4rem);
  --t-lead: clamp(1.06rem, 0.98rem + 0.42vw, 1.28rem);

  --gap: clamp(1rem, 0.5rem + 1.6vw, 2rem);
  --bay: clamp(3.5rem, 2rem + 6vw, 7rem);
  --shell: 1180px;
  --r: 4px;

  --shadow: 0 1px 2px oklch(0.22 0.014 250 / 0.05),
            0 8px 24px -12px oklch(0.22 0.014 250 / 0.18);
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

*, *::before, *::after { box-sizing: border-box; }

/* The hidden attribute only sets display:none at user-agent weight, so any
   component rule that sets a display — .spine is display:flex — silently wins
   and the element stays on screen. Caught by the spine gauge rendering as an
   empty stub on load. Keep this above the component rules. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 1.125rem;      /* 18px — comfortable reading size on screen */
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.018em;
  text-wrap: balance;
  margin: 0;
}

p { margin: 0; text-wrap: pretty; }
a { color: var(--blue); text-underline-offset: 3px; }
a:hover { color: var(--blue-deep); }
img { max-width: 100%; height: auto; display: block; }

.shell { width: min(100% - 2.5rem, var(--shell)); margin-inline: auto; }
.bay { padding-block: var(--bay); }
.lead { font-size: var(--t-lead); color: var(--ink-2); max-width: 58ch; }

/* Eyebrow label ------------------------------------------------------- */
.eyebrow {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green-deep);
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.eyebrow::before {
  content: "";
  width: 1.6rem;
  height: 2px;
  background: var(--green);
}

/* Buttons ------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 48px;
  padding: 0.8rem 1.5rem;
  border: 1px solid transparent;
  border-radius: var(--r);
  font-family: var(--body);
  font-size: 1rem;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease),
              transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.btn--primary { background: var(--blue); color: #fff; box-shadow: var(--shadow); }
.btn--primary:hover { background: var(--blue-deep); color: #fff; transform: translateY(-1px); }
.btn--ghost { border-color: var(--rule); color: var(--ink); background: transparent; }
.btn--ghost:hover { border-color: var(--blue); color: var(--blue); background: var(--blue-tint); }
.btn:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

/* Header -------------------------------------------------------------- */
.masthead {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in oklab, var(--paper) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--rule);
}
.masthead__in {
  display: flex;
  align-items: center;
  gap: var(--gap);
  min-height: 74px;
}
.masthead__logo img { height: 40px; width: auto; }
.nav { display: flex; gap: 1.6rem; margin-left: auto; }
.nav a {
  position: relative;
  color: var(--ink-2);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.94rem;
  padding-block: 0.4rem;
}
.nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--green);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.28s var(--ease);
}
.nav a:hover, .nav a[aria-current="page"] { color: var(--ink); }
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }
@media (max-width: 900px) { .nav { display: none; } }

/* Hero ---------------------------------------------------------------- */
.hero {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(70ch 44ch at 82% -8%, var(--green-tint), transparent 62%),
    radial-gradient(60ch 40ch at 8% 4%, var(--blue-tint), transparent 60%);
}
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr);
  gap: clamp(2rem, 1rem + 4vw, 4.5rem);
  align-items: center;
}
@media (max-width: 940px) { .hero__grid { grid-template-columns: 1fr; } }
.hero h1 { font-size: var(--t-hero); margin-block: 1.1rem 1.25rem; }
.hero h1 em {
  font-style: normal;
  color: var(--blue);
  position: relative;
  white-space: nowrap;
}
.hero h1 em::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -0.14em;
  height: 0.42em;
  background: no-repeat center/100% 100%
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 20' preserveAspectRatio='none'%3E%3Cpath d='M2 15C40 4 76 3 100 9c24 6 60 5 98-6' fill='none' stroke='%237ac143' stroke-width='5' stroke-linecap='round'/%3E%3C/svg%3E");
}
.hero__cta { display: flex; flex-wrap: wrap; gap: 0.8rem; margin-top: 2rem; }

/* Estimator ------------------------------------------------------------ */
.estimator {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 8px;
  padding: clamp(1.4rem, 1rem + 1.4vw, 2rem);
  box-shadow: 0 2px 4px oklch(0.22 0.014 250 / 0.04),
              0 24px 56px -24px oklch(0.22 0.014 250 / 0.28);
}
.estimator h2 { font-size: var(--t-h3); margin-bottom: 0.25rem; }
.estimator__note { font-size: 0.86rem; color: var(--ink-3); margin-bottom: 1.3rem; }
.field { display: grid; gap: 0.4rem; margin-bottom: 1rem; }
.field label { font-size: 0.82rem; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; color: var(--ink-2); }
.field select, .field input {
  min-height: 46px;
  padding: 0.6rem 0.8rem;
  font: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: var(--paper-2);
  border: 1px solid var(--rule-strong);
  border-radius: var(--r);
}
.field select:focus, .field input:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px var(--blue-tint);
}
.estimator__row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.8rem; }
.estimator__out {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1.4rem;
  padding-top: 1.3rem;
  border-top: 1px dashed var(--rule);
}
.estimator__label { font-size: 0.82rem; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; color: var(--ink-2); }
.estimator__price {
  font-family: var(--display);
  font-size: clamp(1.9rem, 1.4rem + 1.6vw, 2.5rem);
  font-weight: 600;
  color: var(--blue-deep);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.estimator__per { font-size: 0.88rem; color: var(--ink-3); display: block; margin-top: 0.3rem; }
.estimator .btn { width: 100%; justify-content: center; margin-top: 1.2rem; }

/* Stats ---------------------------------------------------------------- */
.stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gap); }
@media (max-width: 780px) { .stats { grid-template-columns: 1fr; } }
.stat { border-top: 3px solid var(--green); padding-top: 1.1rem; }
.stat__n {
  font-family: var(--display);
  font-size: clamp(2.1rem, 1.5rem + 2.2vw, 3.1rem);
  font-weight: 600;
  line-height: 1;
  color: var(--blue-deep);
  font-variant-numeric: tabular-nums;
}
.stat__t { color: var(--ink-2); margin-top: 0.5rem; }

/* Two doors ------------------------------------------------------------ */
.doors { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gap); }
@media (max-width: 820px) { .doors { grid-template-columns: 1fr; } }
.door {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: clamp(1.6rem, 1.2rem + 1.6vw, 2.4rem);
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 8px;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
}
.door:hover { transform: translateY(-3px); border-color: var(--blue); box-shadow: var(--shadow); }
.door h3 { font-size: var(--t-h3); }
.door ul { margin: 0; padding-left: 1.1rem; color: var(--ink-2); display: grid; gap: 0.4rem; }
.door__link { margin-top: auto; font-weight: 700; text-decoration: none; }
.door__link::after { content: " \2192"; }

/* Process -------------------------------------------------------------- */
.steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gap); counter-reset: s; }
@media (max-width: 820px) { .steps { grid-template-columns: 1fr; } }
.step { counter-increment: s; position: relative; padding-top: 3.2rem; }
.step::before {
  content: counter(s, decimal-leading-zero);
  position: absolute;
  top: 0; left: 0;
  font-family: var(--display);
  font-size: 1.6rem;
  font-weight: 600;
  color: var(--green-deep);
}
.step::after {
  content: "";
  position: absolute;
  top: 1.5rem; left: 2.6rem; right: -1rem;
  height: 1px;
  background: var(--rule);
}
.step:last-child::after { display: none; }
@media (max-width: 820px) { .step::after { display: none; } }
.step h3 { font-size: var(--t-h3); margin-bottom: 0.5rem; }
.step p { color: var(--ink-2); }

/* Capability table ----------------------------------------------------- */
.specs { width: 100%; border-collapse: collapse; font-size: 0.98rem; }
.specs caption { text-align: left; color: var(--ink-3); font-size: 0.88rem; padding-bottom: 0.8rem; }
.specs th, .specs td { text-align: left; padding: 0.85rem 1rem; border-bottom: 1px solid var(--rule); }
.specs th { font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); font-weight: 700; }
.specs tbody tr { transition: background 0.2s var(--ease); }
.specs tbody tr:hover { background: var(--green-tint); }
.specs td:last-child { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.specs__wrap { overflow-x: auto; }

/* CTA band ------------------------------------------------------------- */
.cta {
  background: var(--blue-deep);
  color: #fff;
  border-radius: 10px;
  padding: clamp(2.2rem, 1.6rem + 2.6vw, 3.6rem);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap);
}
.cta h2 { color: #fff; font-size: var(--t-h2); max-width: 20ch; }
.cta p { color: var(--dark-ink); margin-top: 0.6rem; max-width: 46ch; }
.cta .btn--primary { background: var(--green); color: var(--ink); }
.cta .btn--primary:hover { background: #fff; color: var(--blue-deep); }

/* Footer --------------------------------------------------------------- */
.foot { background: var(--foot-bg); color: var(--dark-ink-2); padding-block: clamp(2.5rem, 2rem + 2vw, 4rem) 2rem; }
.foot__grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: var(--gap); }
@media (max-width: 820px) { .foot__grid { grid-template-columns: 1fr; } }
.foot h4 { font-family: var(--body); font-size: 0.78rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--foot-ink-3); margin: 0 0 0.9rem; }
.foot a { color: var(--dark-ink); text-decoration: none; }
.foot a:hover { color: var(--foot-link); }
.foot__addr { margin-top: 1rem; max-width: 34ch; }
.foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.55rem; }
.foot__base { margin-top: 2.6rem; padding-top: 1.4rem; border-top: 1px solid var(--foot-rule); font-size: 0.86rem; color: var(--foot-ink-3); }

/* Reveal on scroll ------------------------------------------------------ */
/* Content is visible by default; JS opts in to animating it (see the inline
   head script). A script failure must never hide the page. */
.js-reveal .reveal { opacity: 0; transform: translateY(16px); }
.reveal { transition: opacity 0.7s var(--ease), transform 0.7s var(--ease); }
.js-reveal .reveal.is-in { opacity: 1; transform: none; }
.reveal-d1 { transition-delay: 80ms; }
.reveal-d2 { transition-delay: 160ms; }
.reveal-d3 { transition-delay: 240ms; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
  .js-reveal .reveal { opacity: 1; transform: none; }
}

/* Cross-page morphing, progressively enhanced */
@view-transition { navigation: auto; }

/* Signature: live spine gauge -------------------------------------------
   Spine thickness renders at true relative scale as pages/paper change.
   Cover designers need this number; no competitor surfaces it. */
.spine {
  display: flex;
  align-items: flex-end;
  gap: 0.9rem;
  margin-top: 1.3rem;
  padding-top: 1.2rem;
  border-top: 1px dashed var(--rule);
}
.spine__stack {
  display: flex;
  align-items: flex-end;
  height: 92px;
}
.spine__block {
  width: 12px;                       /* set live by JS to true scale */
  height: 92px;
  background: linear-gradient(90deg,
    var(--blue-deep) 0 2px,
    var(--paper-2) 2px calc(100% - 1px),
    var(--rule) calc(100% - 1px));
  border: 1px solid var(--rule);
  border-left-color: var(--blue-deep);
  border-radius: 1px 2px 2px 1px;
  transition: width 0.45s var(--ease);
  position: relative;
}
/* page edges */
.spine__block::after {
  content: "";
  position: absolute;
  inset: 3px 2px 3px 3px;
  background: repeating-linear-gradient(90deg,
    var(--rule) 0 0.5px, transparent 0.5px 2.5px);
  opacity: 0.5;
}
.spine__meta { display: grid; gap: 0.15rem; }
.spine__mm {
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.spine__cap { font-size: 0.78rem; color: var(--ink-3); }

/* Skip link -------------------------------------------------------------- */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--ink);
  color: #fff;
  padding: 0.8rem 1.2rem;
  border-radius: 0 0 var(--r) 0;
}
.skip:focus { left: 0; color: #fff; }

/* Mobile nav ------------------------------------------------------------- */
.burger {
  display: none;
  margin-left: auto;
  width: 46px; height: 46px;
  background: none;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  cursor: pointer;
  padding: 0 11px;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
}
.burger span { display: block; width: 100%; height: 2px; background: var(--ink); transition: transform 0.25s var(--ease), opacity 0.2s; }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
.mnav { display: none; }
@media (max-width: 900px) {
  .burger { display: flex; }
  .masthead__cta { display: none; }
  .mnav {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.32s var(--ease);
    border-top: 0 solid var(--rule);
  }
  .mnav.is-open { grid-template-rows: 1fr; border-top-width: 1px; }
  /* All links live in one grid child so the whole menu collapses as a single
     row. (Applying 0fr with the links as direct children only collapsed the
     first row — About — and left the rest visible.) */
  .mnav__inner { min-height: 0; overflow: hidden; }
  .mnav__inner > a {
    display: block;
    padding: 0 1.25rem;
    line-height: 3.1;
    color: var(--ink);
    text-decoration: none;
    font-weight: 700;
    border-bottom: 1px solid var(--rule);
  }
}

/* Page header (interior pages) ------------------------------------------- */
.phead {
  border-bottom: 1px solid var(--rule);
  background:
    linear-gradient(var(--paper-2), var(--paper));
}
.phead__in { padding-block: clamp(2.6rem, 2rem + 3vw, 4.6rem); }
.phead h1 { font-size: var(--t-h2); margin-block: 0.9rem 1rem; max-width: 20ch; }

/* Prose (long-form body copy) -------------------------------------------- */
.prose { max-width: 68ch; }
.prose > * + * { margin-top: 1.15rem; }
.prose p, .prose li { color: var(--ink-2); }
.prose h2 { font-size: var(--t-h3); margin-top: 2.4rem; color: var(--ink); }
.prose ul { padding-left: 1.15rem; display: grid; gap: 0.55rem; }
.prose strong { color: var(--ink); }

/* Pull quote — used once per page, sparingly */
.pull {
  font-family: var(--display);
  font-size: clamp(1.35rem, 1.05rem + 1.3vw, 1.95rem);
  line-height: 1.32;
  color: var(--ink);
  border-left: 3px solid var(--green);
  padding-left: clamp(1rem, 0.7rem + 1vw, 1.6rem);
  margin-block: 2.4rem;
  max-width: 34ch;
}

/* Feature cards ---------------------------------------------------------- */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(255px, 1fr)); gap: var(--gap); }
.card {
  padding: clamp(1.4rem, 1.1rem + 1.2vw, 2rem);
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 8px;
}
.card h3 { font-size: var(--t-h3); margin-bottom: 0.55rem; }
.card p { color: var(--ink-2); }
.card__icon { color: var(--green-deep); margin-bottom: 0.9rem; }

/* Contact layout --------------------------------------------------------- */
.contact__grid { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: clamp(2rem, 1.2rem + 3vw, 4rem); align-items: start; }
@media (max-width: 900px) { .contact__grid { grid-template-columns: 1fr; } }
.field textarea {
  min-height: 140px;
  padding: 0.7rem 0.8rem;
  font: inherit;
  color: var(--ink);
  background: var(--paper-2);
  border: 1px solid var(--rule-strong);
  border-radius: var(--r);
  resize: vertical;
}
.field textarea:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-tint); }
.contact__detail { display: grid; gap: 1.6rem; }
.contact__detail h3 { font-size: 0.78rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); font-family: var(--body); font-weight: 700; margin-bottom: 0.4rem; }

/* Notice — honest placeholder, never dressed as content ------------------- */
.notice {
  border: 1px dashed var(--rule);
  border-radius: 8px;
  padding: clamp(1.4rem, 1.1rem + 1.2vw, 2rem);
  background: var(--paper-2);
  color: var(--ink-2);
  max-width: 62ch;
}
.notice strong { color: var(--ink); }
/* Outcome variants. The dashed default says "nothing here yet"; a solid edge
   says "this is a reply to what you just did". */
.notice--ok  { border-style: solid; border-color: var(--green); }
.notice--err { border-style: solid; border-color: var(--rule-strong); }

/* Section heading — the standard lead-in under an eyebrow ---------------- */
.sec-h {
  font-size: var(--t-h2);
  margin-block: 0.8rem 2.4rem;
  max-width: 24ch;
}

/* Footer logo — reversed out of the dark ground -------------------------- */
.foot__logo {
  height: 36px;
  width: auto;
  /* The logo is dark blue on transparent; lift it so it reads on --ink */
  filter: brightness(0) invert(1);
  opacity: 0.92;
}

/* Form overflow fixes ----------------------------------------------------
   Grid children default to min-content width, so a long input can push past
   its track. Pin them to the track and let the paired row stack on narrow
   screens. (Caught by a 390px overflow on /contact.) */
.field input,
.field select,
.field textarea { width: 100%; min-width: 0; }

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

/* reCAPTCHA renders at a fixed 302px; let it scroll rather than widen the page */
.g-recaptcha { max-width: 100%; overflow-x: auto; }

/* ===========================================================================
   Interior page craft
   =========================================================================== */

/* Page header — asymmetric, with a hairline and an oversized folio mark ---- */
.phead { position: relative; overflow: hidden; }
.phead__in { position: relative; z-index: 1; }
.phead__folio {
  position: absolute;
  right: -0.06em;
  bottom: -0.34em;
  z-index: 0;
  font-family: var(--display);
  font-size: clamp(9rem, 5rem + 22vw, 22rem);
  line-height: 0.8;
  color: var(--blue);
  opacity: 0.055;
  pointer-events: none;
  user-select: none;
}

/* Drop cap — bookish, and appropriate for a printer. Used once per page. --- */
.dropcap::first-letter {
  float: left;
  font-family: var(--display);
  font-size: 3.6em;
  line-height: 0.82;
  padding: 0.08em 0.14em 0 0;
  color: var(--blue-deep);
}

/* Proof band — real figures from our own production record ---------------- */
.proof { background: var(--ink); color: var(--dark-ink); }
.proof__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--gap);
  padding-block: clamp(2.4rem, 1.8rem + 2.4vw, 3.6rem);
}
@media (max-width: 860px) { .proof__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 460px) { .proof__grid { grid-template-columns: 1fr; } }
.proof__n {
  font-family: var(--display);
  font-size: clamp(1.9rem, 1.4rem + 1.9vw, 2.8rem);
  line-height: 1;
  color: #fff;
  font-variant-numeric: tabular-nums;
}
.proof__t { font-size: 0.9rem; color: var(--dark-ink-3); margin-top: 0.5rem; max-width: 22ch; }
.proof__rule { height: 2px; width: 2rem; background: var(--green); margin-bottom: 1rem; }

/* Specimen — trim sizes drawn at true relative scale.
   Companion to the spine gauge: both show real physical dimension. --------- */
.specimen { display: flex; flex-wrap: wrap; align-items: flex-end; gap: clamp(1.2rem, 0.8rem + 2vw, 2.6rem); }
.spec-card { display: grid; gap: 0.7rem; justify-items: center; }
.spec-card__paper {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 1px 3px 3px 1px;
  box-shadow: var(--shadow);
  position: relative;
}
/* spine hint down the binding edge */
.spec-card__paper::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--blue-deep);
  border-radius: 1px 0 0 1px;
  opacity: 0.75;
}
.spec-card__label { font-size: 0.82rem; color: var(--ink-2); text-align: center; font-variant-numeric: tabular-nums; }
.spec-card__count { font-size: 0.76rem; color: var(--ink-3); }

/* Figure with caption ----------------------------------------------------- */
.figure { margin: 0; }
.figure img { border-radius: 6px; border: 1px solid var(--rule); width: 100%; }
.figure figcaption { font-size: 0.84rem; color: var(--ink-3); margin-top: 0.7rem; }

/* Bar row — proportional, for the real binding mix ------------------------ */
.mix { display: grid; gap: 0.9rem; }
.mix__row { display: grid; grid-template-columns: 12rem 1fr auto; gap: 1rem; align-items: center; }
@media (max-width: 620px) { .mix__row { grid-template-columns: 8rem 1fr auto; } }
.mix__bar { height: 10px; background: var(--paper-3, var(--paper-2)); border-radius: 999px; overflow: hidden; }
.mix__fill {
  height: 100%;
  background: var(--blue);
  border-radius: 999px;
  transform-origin: left;
  transition: transform 0.9s var(--ease);
}
/* Bars are drawn at full width by default; only the animated path starts at
   zero, so reduced motion or a dead script still shows the data. */
.js-reveal .mix__fill { transform: scaleX(0); }
.js-reveal .is-in .mix__fill { transform: scaleX(1); }
.mix__n { font-variant-numeric: tabular-nums; color: var(--ink-2); font-size: 0.92rem; }
.mix__label { color: var(--ink); font-weight: 700; font-size: 0.94rem; }

/* Error page -------------------------------------------------------------- */
.err { display: grid; place-items: center; text-align: center; min-height: 56vh; gap: 1.2rem; }
.err h1 { font-size: var(--t-hero); }
.err .eyebrow, .err .hero__cta { justify-content: center; }
.err .lead { margin-inline: auto; }

/* Estimator result ------------------------------------------------------- */
.estimator__result { margin-top: 1.4rem; padding-top: 1.3rem; border-top: 1px dashed var(--rule); min-height: 4.5rem; }

/* FAQ -------------------------------------------------------------------- */
.faq { display: grid; gap: 0; max-width: 74ch; border-top: 1px solid var(--rule); }
.faq__item { border-bottom: 1px solid var(--rule); }
.faq__q {
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.5rem 0 0.8rem;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  font-family: var(--display);
  font-size: clamp(1.2rem, 1.02rem + 0.62vw, 1.55rem);
  font-weight: 700;
  color: var(--ink);
  line-height: 1.25;
  letter-spacing: -0.012em;
}
.faq__q:hover { color: var(--blue); }
.faq__q:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.faq__q::after {
  content: "";
  flex: none;
  width: 13px; height: 13px;
  margin-top: 0.35rem;
  border-right: 2px solid var(--green-deep);
  border-bottom: 2px solid var(--green-deep);
  transform: rotate(45deg);
  transition: transform 0.28s var(--ease);
}
.faq__q[aria-expanded="true"]::after { transform: rotate(-135deg); }
.faq__a {
  padding: 0 0 1.6rem;
  color: var(--ink-2);
  max-width: 68ch;
  font-size: 1.06rem;
  line-height: 1.7;
}
.faq__a > * + * { margin-top: 0.8rem; }

/* Counting numbers --------------------------------------------------------
   The final value is rendered server-side and animation only replaces it when
   JS is alive and motion is welcome, so the figure is never missing. */
.count { font-variant-numeric: tabular-nums; }

/* Client logo placeholders ------------------------------------------------
   Deliberately empty frames: we do not publish client names without
   permission, and the originals belonged to another printer. */
/* 1 x 4 scrollable row — compact slots, swipe on narrow screens */
/* Exactly four slots in view; the rest scroll. Two across on phones. */
.logos {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc((100% - 3 * 1rem) / 4);
  gap: 1rem;
  overflow-x: auto;
  padding-bottom: 0.6rem;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
}
@media (max-width: 700px) {
  .logos { grid-auto-columns: calc((100% - 1rem) / 2); }
}
.logos::-webkit-scrollbar { height: 6px; }
.logos::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 999px; }
.logo-slot {
  display: grid;
  place-items: center;
  gap: 0.35rem;
  scroll-snap-align: start;
  width: 100%;
  height: 80px;
  padding: 0.7rem;
  border: 1px dashed var(--rule);
  border-radius: 6px;
  background: var(--paper-2);
  color: var(--ink-3);
  text-align: center;
}
.logo-slot__mark {
  width: 24px; height: 24px;
  color: var(--rule);
}
.logo-slot__label { font-size: 0.7rem; letter-spacing: 0.06em; text-transform: uppercase; }

/* Quote form: email field, submit block, result messages ------------------ */
.field--email { margin-top: 1.4rem; padding-top: 1.3rem; border-top: 1px dashed var(--rule); }
.btn--block { width: 100%; justify-content: center; margin-top: 0.4rem; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.estimator__result:empty { display: none; }
.estimator__result { margin-top: 1.2rem; }
.est-msg { padding: 1rem 1.1rem; border-radius: var(--r); font-size: 0.96rem; }
.est-msg > * + * { margin-top: 0.5rem; }
.est-msg ul { margin: 0; padding-left: 1.1rem; display: grid; gap: 0.35rem; }
.est-msg--ok    { background: var(--green-tint); border: 1px solid var(--green); color: var(--ink); }
.est-msg--error { background: var(--paper-2); border: 1px solid var(--rule); color: var(--ink-2); }
.est-msg--info  { background: var(--paper-2); border: 1px solid var(--rule); color: var(--ink-3); }

/* ===========================================================================
   Client feedback — the form on /feedback and the cards on /clients
   =========================================================================== */

/* Form helpers ----------------------------------------------------------- */
.field__opt  { font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--ink-3); }
.field__help { font-size: 0.86rem; color: var(--ink-3); margin-top: 0.1rem; max-width: 54ch; }

.field--check { display: flex; align-items: flex-start; gap: 0.7rem; margin-block: 1.6rem; }
.field--check input { width: 20px; height: 20px; margin-top: 0.2rem; flex: none; accent-color: var(--blue); }
.field--check label {
  font: inherit; font-size: 0.95rem; color: var(--ink-2);
  text-transform: none; letter-spacing: 0; font-weight: 400; line-height: 1.55;
}
.field input[type="file"] {
  font: inherit; font-size: 0.94rem; color: var(--ink-2);
  padding: 0.6rem; background: var(--paper-2);
  border: 1px dashed var(--rule-strong); border-radius: var(--r);
}
.field input[type="file"]::file-selector-button {
  font: inherit; font-size: 0.88rem; font-weight: 700;
  margin-right: 0.8rem; padding: 0.45rem 0.9rem;
  color: var(--ink); background: var(--paper);
  border: 1px solid var(--rule-strong); border-radius: var(--r); cursor: pointer;
}

/* Star rating -------------------------------------------------------------
   Real radio inputs, visually hidden, with the stars painted on their labels.
   Keyboard and screen reader get a normal radio group; everyone else gets
   stars. row-reverse so the CSS sibling selector can light up 1..n. */
.rate { border: 0; padding: 0; margin: 0 0 1.4rem; }
.rate__legend {
  padding: 0;
  font-size: 0.82rem; font-weight: 700; letter-spacing: 0.03em;
  text-transform: uppercase; color: var(--ink-2); margin-bottom: 0.5rem;
}
.rate__set { display: flex; flex-direction: row-reverse; justify-content: flex-end; gap: 0.25rem; }
.rate__in {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
.rate__star { cursor: pointer; line-height: 0; padding: 0.15rem; border-radius: var(--r); }
.rate__star svg { width: 30px; height: 30px; fill: var(--rule); transition: fill 0.15s var(--ease); }
/* The checked star and every star before it (later in DOM order, earlier
   visually, because the row is reversed). */
.rate__in:checked ~ .rate__star svg,
.rate__star:hover svg,
.rate__star:hover ~ .rate__star svg { fill: #f0a500; }
.rate__in:focus-visible + .rate__star { outline: 3px solid var(--focus); outline-offset: 2px; }

/* Testimonial cards -------------------------------------------------------
   A scroll-snap row rather than a JS carousel: it works with no JS, with a
   trackpad, with a touch swipe and with the keyboard. The arrows are an
   enhancement on top, and hide themselves when everything already fits. */
.stories { position: relative; }
.stories__rail {
  display: grid;
  grid-auto-flow: column;
  /* Predictable card width at every viewport. minmax(0,360px) let the track
     collapse to its content (measured 280px), which made the quote read tall
     and narrow. clamp() pins it instead and still fits a 375px phone. */
  grid-auto-columns: clamp(268px, 78vw, 360px);
  gap: var(--gap);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  padding-bottom: 0.8rem;
  scrollbar-width: thin;
}
.stories__rail::-webkit-scrollbar { height: 6px; }
.stories__rail::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 999px; }

.story {
  margin: 0;                  /* <figure> carries a UA margin of 1em 40px, which
                                 was eating 80px of a 360px track */
  scroll-snap-align: start;
  display: flex; flex-direction: column; gap: 1rem;
  padding: clamp(1.3rem, 1rem + 1vw, 1.8rem);
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 8px;
  box-shadow: var(--shadow);
}
.story__top { display: flex; align-items: center; gap: 0.9rem; }
/* Fixed tile so wildly different logo shapes still line up down the row. */
.story__mark {
  flex: none;
  width: 68px; height: 68px;
  display: grid; place-items: center;
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 6px;
  overflow: hidden;
}
.story__mark img { max-width: 82%; max-height: 82%; width: auto; height: auto; object-fit: contain; }
.story__initial { font-family: var(--display); font-size: 1.9rem; font-weight: 600; color: var(--blue-deep); line-height: 1; }
.story__stars { display: flex; gap: 2px; }
.story__stars svg { width: 15px; height: 15px; fill: #f0a500; }
.story__stars svg.is-off { fill: var(--rule); }
.story__q {
  font-family: var(--display); font-size: 1.08rem; line-height: 1.5;
  color: var(--ink); margin: 0; text-wrap: pretty;
}
.story__who { margin-top: auto; padding-top: 0.5rem; border-top: 1px solid var(--rule); }
.story__name { font-weight: 700; font-size: 0.95rem; color: var(--ink); }
.story__meta { font-size: 0.86rem; color: var(--ink-3); margin-top: 0.15rem; }

/* Arrows. Hidden until JS decides the rail actually overflows. */
.stories__nav { display: none; gap: 0.5rem; margin-bottom: 1.1rem; }
.stories__nav.is-on { display: flex; }
.stories__btn {
  width: 42px; height: 42px;
  display: grid; place-items: center;
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  border-radius: var(--r);
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.2s var(--ease), background 0.2s var(--ease), opacity 0.2s var(--ease);
}
.stories__btn:hover:not(:disabled) { border-color: var(--blue); color: var(--blue); background: var(--blue-tint); }
.stories__btn:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.stories__btn:disabled { opacity: 0.35; cursor: default; }
.stories__btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; }
/* ===========================================================================
   Spacing utilities
   ---------------------------------------------------------------------------
   A small, closed set, last in the file so they win a tie against a component
   default. They exist so one-off spacing stops being written as inline style
   attributes — that is how a second, undocumented scale grows, and the audit of
   28 Sep 2026 found eight ad-hoc values (0.8 to 2.4rem) scattered across the
   pages. If you need a value that is not one of these, it belongs in a
   component rule, not here and not in an attribute.
   =========================================================================== */
.mt-0   { margin-top: 0; }
.mt-s   { margin-top: 0.8rem; }
.mt-m   { margin-top: 1.4rem; }
.mt-l   { margin-top: 1.8rem; }
.mb-m   { margin-bottom: 1.4rem; }
.mb-l   { margin-bottom: 1.8rem; }
.mb-xl  { margin-bottom: 2.3rem; }
.pt-0   { padding-top: 0; }
.pb-bay { padding-bottom: var(--bay); }

/* A shorter bay, for stacked sections that would otherwise drift apart. */
.bay--tight { padding-block: clamp(2.2rem, 1.6rem + 2vw, 3.4rem); }

/* Subsection heading — a step below .sec-h, for a titled block inside a bay. */
.sub-h { font-size: var(--t-h3); margin-block: 3.2rem 1.4rem; }

