/* ============================================================
   Wash4You — base
   Tokens, reset, typography, utilities.

   Design thesis: the garment care label. The tag sewn into every
   piece of clothing is this industry's own notation system —
   universally understood, quietly authoritative, and exactly what
   "Safe on Fabric" means in practice. It is the structural device
   for the whole site, not decoration.
   ============================================================ */

:root {
  /* ---- Colour -------------------------------------------------
     Premium fabric-care palette: a deep navy anchor, warm paper
     neutrals, and ONE warm accent — muted brass. Green survives in
     exactly one role: the primary action. Nothing else wears it. */
  --ink:        #101b2e;  /* near-black navy — headings            */
  --ink-2:      #3d4a60;  /* body copy                              */
  --ink-3:      #677283;  /* captions, meta. Darkened from #6b7789:
                             that only reached 4.26:1 on the --wash ground,
                             which is where most captions actually sit.      */

  --navy:       #14336b;  /* brand navy — structure, links          */
  --navy-deep:  #0d2350;  /* dark bands, the anchor                 */
  --navy-tint:  #e9edf6;  /* navy at 8% — quiet fills               */

  /* The client's brand green is #21b14b. White text on it measures 2.82:1,
     so the CTA fill is darkened to pass. Green is the ACTION colour only —
     buttons and nothing else; every other accent job belongs to brass. */
  --green:      #17883b;  /* green TEXT on white — 4.54:1           */
  --green-cta:  #198639;  /* button fill under white text — 4.66:1  */
  --green-deep: #126b2d;  /* pressed                                */
  --green-brand:#21b14b;  /* untouched brand green: logo contexts only */
  --green-tint: #e6f6ec;

  /* ---- The warm accent — muted brass --------------------------
     Gold-on-navy is the category's own signal of care and craft.
     Three legibility steps, measured:
       --brass        decorative marks, rules, stars, borders (2.99:1 on
                      --wash — non-text only)
       --brass-deep   brass TEXT on light grounds (4.7:1 on --wash)
       --brass-bright brass TEXT/marks on navy bands (8.1:1 on --navy-deep) */
  --brass:        #b28a4a;
  --brass-deep:   #7a5c26;
  --brass-bright: #d9b878;
  --brass-tint:   #f6efe1;

  /* Legacy spec aliases — re-pointed at the refined palette so every
     rule that references them inherits the restraint. */
  --brand-blue:      #14336b;  /* was the bright logo blue; now the navy anchor */
  --brand-blue-deep: #14336b;
  --brand-green:     #21b14b;  /* logo green — logo/CTA contexts only */
  --brand-green-cta: #198639;
  --text-body:       #3d4a60;

  --paper:      #ffffff;
  --wash:       #faf8f4;  /* warm paper ground                      */
  --wash-2:     #f3efe7;  /* deeper warm paper                      */
  --line:       #e6e0d4;  /* warm hairline                          */
  --line-soft:  #efebe1;

  /* Stars and notices ride the brass scale — one warm accent, one voice. */
  --amber:      #b28a4a;
  --amber-tint: #f6efe1;
  --amber-deep: #7a5c26;

  /* ---- Type ---------------------------------------------------
     Fraunces is the display face — an elegant transitional serif with a
     live optical-size axis, for headlines and the big numerals. Hanken
     Grotesk is the clean grotesque for body and UI. Plex Mono is the
     docket/ticket voice — eyebrows, counts, codes, captions. */
  --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-sans:    'Hanken Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-mono:    'IBM Plex Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;

  /* Fluid scale — 360px → 1280px viewport */
  --t-xs:   0.8125rem;  /* 13px. The CAPTION FLOOR — dates, legal lines, tax
                          and unit qualifiers, badges. Never a sentence, a
                          link or a control label. Was 0.75rem/12px. */
  --t-sm:   0.9375rem;  /* 15px. Secondary text that is still read, not
                          skimmed. Was 0.8125rem/13px, which 77 rules used
                          for body copy, navigation and control labels. */
  --t-base: 1rem;
  --t-md:   clamp(1.0625rem, 0.99rem + 0.32vw, 1.1875rem);
  --t-lg:   clamp(1.25rem,  1.14rem + 0.48vw, 1.5rem);
  --t-xl:   clamp(1.5rem,   1.31rem + 0.83vw, 2rem);
  --t-2xl:  clamp(1.875rem, 1.55rem + 1.42vw, 2.75rem);
  --t-3xl:  clamp(2.125rem, 1.68rem + 1.98vw, 3.25rem);
  /* Capped at 3.5rem: "Shrink the hassle," has to fit the hero copy column
     in two lines rather than four, or the CTA drops below the fold. */
  --t-4xl:  clamp(2.5rem,   1.95rem + 2.4vw,  3.5rem);

  /* ---- Space -------------------------------------------------- */
  --s-1: 0.25rem;  --s-2: 0.5rem;   --s-3: 0.75rem;  --s-4: 1rem;
  --s-5: 1.5rem;   --s-6: 2rem;     --s-7: 2.5rem;   --s-8: 3rem;
  --s-9: 4rem;     --s-10: 5rem;    --s-11: 6.5rem;

  /* Section rhythm — one variable so vertical spacing never drifts.
     64px on a phone rising to 128px on desktop: sections breathe. */
  --section-y: clamp(4rem, 2.9rem + 4.8vw, 8rem);

  --wrap: 1200px;
  --wrap-narrow: 760px;
  --gutter: clamp(1.125rem, 0.85rem + 1.2vw, 2rem);

  /* ---- Form ---------------------------------------------------
     ONE corner radius. 16px on every card, image and button; 8px only
     for small elements nested inside a 16px parent; pill for chips. */
  --r-sm: 8px;  --r-md: 16px;  --r-lg: 16px;  --r-xl: 16px;  --r-pill: 999px;

  /* Soft, low-opacity layered shadows on the navy axis — never grey. */
  --shadow-sm:  0 1px 2px rgba(13, 35, 80, .04), 0 8px 24px rgba(13, 35, 80, .06);
  --shadow-md:  0 2px 4px rgba(13, 35, 80, .05), 0 12px 32px rgba(13, 35, 80, .09);
  --shadow-lg:  0 4px 12px rgba(13, 35, 80, .07), 0 24px 56px rgba(13, 35, 80, .13);
  --shadow-cta: 0 6px 16px rgba(25, 134, 57, .20);
  --shadow-card: 0 1px 2px rgba(13, 35, 80, .04), 0 8px 24px rgba(13, 35, 80, .06);

  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --ease-in-out: cubic-bezier(.65, 0, .35, 1);

  /* ---- Photography ---------------------------------------------
     ONE treatment for every photo on the site. The sources are a mix
     of studio cut-outs and phone photography; this grade — slightly
     warm, soft contrast, gently desaturated — pulls them into one
     shoot. Applied through .ph / the component selectors below, never
     to logos, icons or the route map. */
  --photo-grade: saturate(.9) sepia(.07) contrast(.96) brightness(1.03);
  --photo-tone: #efe9dd;   /* the one studio ground behind cut-outs */
}

/* The shared photographic voice. Put the class on the <img> itself or
   lean on the component selectors that opt whole slots in. */
.ph, .ph img { filter: var(--photo-grade); }

/* ============================================================
   Reset
   ============================================================ */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Offset for the sticky header when jumping to an anchor, plus the
     pinned offer strip's measured height (--promo-h, set by base.html) —
     the header now docks below that strip instead of at the true top, so
     an anchor target needs to clear both to land in view, not just the
     header. */
  scroll-padding-top: calc(5.5rem + var(--promo-h, 0px));
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-2);
  font-family: var(--font-sans);
  /* Body 16 → 17px, line-height 1.6 (spec req 7) */
  font-size: clamp(1rem, 0.985rem + 0.08vw, 1.0625rem);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, picture, svg, video { display: block; max-width: 100%; }
img, video { height: auto; }

button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; }

ul, ol { margin: 0; padding: 0; list-style: none; }
figure, blockquote, p, h1, h2, h3, h4 { margin: 0; }

a { color: inherit; text-decoration: none; }

/* Visible keyboard focus everywhere. Never remove this. */
:focus-visible {
  outline: 3px solid var(--navy);
  outline-offset: 3px;
  border-radius: 3px;
}

::selection { background: var(--navy); color: #fff; }

/* ============================================================
   Typography
   ============================================================ */

/* Display headlines set in the serif: confident, tightened, never bold-y.
   Fraunces' optical-size axis follows the rendered size automatically. */
h1, h2, .display {
  font-family: var(--font-display);
  color: var(--ink);
  line-height: 1.1;
  letter-spacing: -0.015em;
  text-wrap: balance;
  font-optical-sizing: auto;
  font-weight: 600;
}

/* Support headings stay in the clean grotesque — card titles and UI
   headings read as interface, not editorial. */
h3, h4 {
  font-family: var(--font-sans);
  color: var(--ink);
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-wrap: balance;
  font-weight: 700;
}

/* Global type scale — one scale for the whole site, no per-section
   overrides. H1 30→52px, H2 26→40px, H3 20→24px. */
h1, .h1 { font-size: clamp(1.875rem, 1.35rem + 2.3vw, 3.25rem); }
h2, .h2 { font-size: clamp(1.625rem, 1.32rem + 1.35vw, 2.5rem); }
h3, .h3 { font-size: clamp(1.25rem, 1.16rem + 0.4vw, 1.5rem); line-height: 1.2; }
h4, .h4 { font-size: var(--t-lg); line-height: 1.2; font-weight: 700; }

.display-xl {
  font-family: var(--font-display);
  font-size: clamp(1.875rem, 1.35rem + 2.3vw, 3.25rem);
  font-weight: 600;
  font-optical-sizing: auto;
  letter-spacing: -0.015em;
  line-height: 1.08;
  color: var(--ink);
  text-wrap: balance;
}

/* Small print (spec req 7) */
.small, small { font-size: 0.875rem; }   /* 14px */

p { text-wrap: pretty; text-align: justify; text-justify: inter-word; hyphens: auto; }
p + p { margin-top: var(--s-4); }
/* Justify only reads well once a line wraps at least twice; on a single
   short line (eyebrows) it just stretches word-gaps for no reason. */
.eyebrow { text-align: inherit; }

strong, b { font-weight: 700; color: var(--ink); }

/* The docket voice — counts, codes, captions, care-label text.
   Always uppercase, always tracked out, always small. */
.mono {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* A readable variant for sentence/paragraph-length notes (pricing, steam-iron,
   package disclaimers). Keeps the mono voice but drops the uppercasing and
   heavy tracking that make running copy hard to read. Templates opt in with
   `class="mono mono--note"`; short labels keep plain .mono (uppercase). */
.mono--note {
  font-size: var(--t-sm);
  letter-spacing: .02em;
  text-transform: none;
}

/* Eyebrow above a section heading — a refined kicker in the accent.
   Small, tracked at .1em, muted; the short brass rule reads as a stitch. */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--brass-deep);
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-4);
}
.eyebrow::before {
  content: '';
  width: 1.5rem;
  height: 1px;
  background: var(--brass);
  flex: none;
}
.eyebrow--center { justify-content: center; }

.lede {
  font-size: var(--t-lg);
  line-height: 1.5;
  color: var(--ink-2);
  font-weight: 400;
  text-wrap: pretty;
}

/* ---- Headline keyword highlight — golden, on any page ---------------
   Was defined per-page (redesign-pricing.css, redesign-areas.css); moved
   here so every H1 across the site can use the same brass-italic keyword
   without redeclaring it. Those two sheets keep their own copies too —
   identical rule, loaded later, no conflict. */
.kw {
  font-style: italic;
  font-weight: 480;
  color: var(--brass-bright);
}
.kw-text { color: var(--brass-deep); }
/* brass-bright is a pale gold — 1.5:1 on white, illegible there. Every
   existing .kw sits on a navy/photo hero; this variant is for the plain
   .page-hero pages (about, services, packages, contact, blog), whose
   ground is --paper, using brass-deep at 4.7:1 instead. */
.kw--onlight {
  font-style: italic;
  font-weight: 480;
  color: var(--brass-deep);
}

/* ---- Body-copy keyword highlight — neon, logo green -------------------
   For a word or short phrase inside a paragraph, not a headline. The
   untouched brand green (#21b14b) is reserved for logo/dark-ground use
   elsewhere in this codebase — on a light paragraph it is ~2.6:1, below
   AA — so light grounds get --green-cta (4.66:1) instead, with a glow to
   still read as "lit". Dark/navy sections get the real logo green, which
   has plenty of contrast there. Keep it to 1-2 words per block — it is an
   accent, not a new text colour for the page. */
.neon-kw {
  color: var(--green-cta);
  font-weight: 700;
  text-shadow: 0 0 .25em rgba(25, 134, 57, .35);
}
.section--navy .neon-kw,
.home-hero .neon-kw,
.svc-hero .neon-kw,
.pricing-hero .neon-kw,
.areas-hero .neon-kw {
  color: var(--brand-green);
  text-shadow: 0 0 .35em rgba(33, 177, 75, .65);
}

/* ============================================================
   Layout primitives
   ============================================================ */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap--narrow { max-width: var(--wrap-narrow); }

.section { padding-block: var(--section-y); }
.section--tight { padding-block: calc(var(--section-y) * .62); }
.section--wash { background: var(--wash); }
.section--navy { background: var(--navy-deep); color: rgba(255,255,255,.9); }
.section--navy h1, .section--navy h2, .section--navy h3, .section--navy h4 { color: #fff; }
.section--navy .eyebrow { color: var(--brass-bright); }
.section--navy .eyebrow::before { background: var(--brass); }
/* .section-head p sets --ink-2 (line 276) and out-specifies the .section--navy
   `color` above, so the lede under every dark-band heading was #3d4a60 on
   #0d2350 — 1.71:1, i.e. invisible. This is 12.1:1. */
/* :not(.eyebrow) — the eyebrow is also a <p> inside .section-head, and this
   rule loads after the #8fb4ff one above, so an unqualified selector turned
   every dark-band eyebrow white. */
.section--navy .section-head p:not(.eyebrow) { color: rgba(255, 255, 255, .84); }

/* A hairline that reads as a stitched seam rather than a border. */
.seam {
  height: 1px;
  background: repeating-linear-gradient(
    to right,
    var(--line) 0 6px,
    transparent 6px 12px
  );
  border: 0;
  margin: 0;
}

.section-head { max-width: 46rem; margin-bottom: var(--s-8); }
.section-head--center { margin-inline: auto; text-align: center; }
.section-head p { margin-top: var(--s-4); font-size: var(--t-md); color: var(--ink-2); }

/* ============================================================
   Utilities
   ============================================================ */

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

.skip-link {
  position: absolute;
  top: 0; left: 50%;
  transform: translate(-50%, -110%);
  z-index: 200;
  background: var(--navy);
  color: #fff;
  padding: var(--s-3) var(--s-5);
  border-radius: 0 0 var(--r-md) var(--r-md);
  font-weight: 600;
}
.skip-link:focus { transform: translate(-50%, 0); }

.text-center { text-align: center; }
.stack > * + * { margin-top: var(--s-4); }
.no-wrap { white-space: nowrap; }
