/* BwB Template Sites - shared design tokens + layout kit
   v1.0 | 2026-07-09 | grounded in KB web-dev/website-design-and-build (M2/M3/M4)
   Per-client: override the THEME block only. Never edit the kit per client. */

/* WEB FONTS. Self-hosted latin subsets from Fontsource 5.3.0 (SIL OFL 1.1; the licences
   sit next to the files in shared/fonts/). They used to load from Google Fonts after first
   paint, and the swap reflowed the header (2026-10-12 audit, finding 1: CLS up to 0.33).
   font-display:optional plus a preload on each page means a face that is not ready by
   first paint is used from the next page view on, never swapped in under the reader.
   A browser downloads only the faces a page actually uses. */
@font-face{font-family:"Oswald";font-style:normal;font-weight:200 700;font-display:optional;src:url(fonts/oswald-latin-wght-normal.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Fraunces";font-style:normal;font-weight:100 900;font-display:optional;src:url(fonts/fraunces-latin-wght-normal.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Fraunces";font-style:italic;font-weight:100 900;font-display:optional;src:url(fonts/fraunces-latin-wght-italic.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Jost";font-style:normal;font-weight:100 900;font-display:optional;src:url(fonts/jost-latin-wght-normal.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Jost";font-style:italic;font-weight:100 900;font-display:optional;src:url(fonts/jost-latin-wght-italic.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Marcellus";font-style:normal;font-weight:400;font-display:optional;src:url(fonts/marcellus-latin-400-normal.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Montserrat";font-style:normal;font-weight:100 900;font-display:optional;src:url(fonts/montserrat-latin-wght-normal.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Karla";font-style:normal;font-weight:200 800;font-display:optional;src:url(fonts/karla-latin-wght-normal.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Karla";font-style:italic;font-weight:200 800;font-display:optional;src:url(fonts/karla-latin-wght-italic.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

:root{
  /* THEME - per-template defaults; per-client overrides go here */
  --color-primary: #2F5D3A;        /* T1 pine (T2 #B4552D terracotta, T3 #23617A lake, T4 #5B4A68 plum) */
  --color-primary-dark: #244A2D;
  --color-accent: #C77D2B;         /* sparing use only — 3.3:1 on white: decorative / large-text only, not body text */
  /* Neutral ramp - tinted toward brand hue, never pure #000 */
  --color-text: #1B211D;
  --color-text-muted: #57605A;
  --color-border: #E1E6E2;
  --color-surface: #F5F7F5;
  --color-bg: #FFFFFF;
  --color-success: #2E7D5B; --color-warning: #B5851A; --color-error: #B82F2F;
  /* --color-warning #B5851A is ~3.3:1 on white — decorative / large-text only, not body text */

  /* SPACING - 8pt scale (KB M2: allowed 4,8,12,16,24,32,48,64,96) */
  --space-1: .25rem; --space-2: .5rem; --space-3: .75rem; --space-4: 1rem;
  --space-5: 1.5rem; --space-6: 2rem; --space-7: 3rem; --space-8: 4rem; --space-9: 6rem;

  /* TYPE - 1.25 modular scale, body 18px, fluid display via clamp (rem-based so zoom works) */
  --text-sm: .875rem; --text-base: 1.125rem; --text-lg: 1.25rem;
  --text-xl: 1.5rem; --text-2xl: 1.875rem; --text-3xl: 2.25rem;
  --text-display: clamp(1.875rem, 1.2rem + 2.5vw, 3rem);

  --radius: 8px;
  --header-h: 64px;   /* KB M1: 56-72px */
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--color-bg);color:var(--color-text);
  font:400 var(--text-base)/1.6 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;}
img,video{max-width:100%;height:auto}
h1,h2,h3{line-height:1.2;color:var(--color-text)}
h1{font-size:var(--text-display);margin:0 0 var(--space-4)}
h2{font-size:var(--text-2xl);margin:0 0 var(--space-4)}
h3{font-size:var(--text-lg);margin:0 0 var(--space-2)}
p{margin:0 0 var(--space-4)}
a{color:var(--color-primary)}
:focus-visible{outline:3px solid var(--color-primary);outline-offset:2px;border-radius:4px}
[id]{scroll-margin-top:calc(var(--header-h) + var(--space-4))} /* KB M4: SC 2.4.11 */

/* LAYOUT KIT (KB M2 primitives - verbatim) */
.section{padding-block:var(--space-8)}
.section--tinted{background:var(--color-surface)}
.container{width:min(72rem,100% - 2*var(--space-4));margin-inline:auto}
.prose{max-width:65ch}
.grid-cards{display:grid;gap:var(--space-5);grid-template-columns:repeat(auto-fit,minmax(min(16rem,100%),1fr))}
.stack>*+*{margin-top:var(--space-3)}

/* COMPONENTS */
.btn{display:inline-block;padding:.75rem 1.25rem;font-weight:600;border-radius:var(--radius);
  text-decoration:none;border:2px solid transparent;min-height:44px;cursor:pointer;
  font-size:var(--text-base);line-height:1.3}
.btn--primary{background:var(--color-primary);color:#fff}
.btn--primary:hover{background:var(--color-primary-dark)}
.btn--secondary{background:transparent;color:var(--color-primary);border-color:var(--color-primary)}
.card{background:var(--color-bg);border:1px solid var(--color-border);border-radius:var(--radius);
  padding:var(--space-5)}
.badge{display:inline-block;font-size:var(--text-sm);font-weight:600;padding:2px 10px;
  border-radius:999px;background:var(--color-surface);border:1px solid var(--color-border)}
.field{display:block;margin-bottom:var(--space-4)}
.field label{display:block;font-weight:600;margin-bottom:var(--space-1)}
.field input,.field textarea,.field select{width:100%;min-width:0;padding:.65rem .75rem;font:inherit;
  border:1px solid var(--color-border);border-radius:var(--radius);background:#fff;color:var(--color-text)}

/* CHROME */
.site-header{position:sticky;top:0;z-index:10;background:var(--color-bg);
  border-bottom:1px solid var(--color-border);min-height:var(--header-h)}
.skip-link{position:absolute;left:-9999px;top:0;background:var(--color-primary);color:#fff;
  padding:var(--space-2) var(--space-4);z-index:20}
.skip-link:focus{left:var(--space-4);top:var(--space-2)}
.site-footer{background:var(--color-surface);border-top:1px solid var(--color-border);
  padding-block:var(--space-7);font-size:var(--text-sm);color:var(--color-text-muted)}
.cta-band{background:var(--color-primary);color:#fff;text-align:center}
.cta-band h2,.cta-band p{color:#fff}
.cta-band .btn--primary{background:#fff;color:var(--color-primary)}
/* Text for screen readers only - e.g. "(opens in a new tab)" on external links. */
.visually-hidden{position:absolute!important;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* PHONE HEADER. Below 48rem the header scrolls away with the page instead of
   sticking: at large text sizes a pinned header eats the screen and hides focused
   controls (SC 2.4.11). Each template keeps its one main action, Call, as a visible
   button in the header at every width (KB module-03, mobile nav). The bottom action
   bar that used to carry it was removed on 2026-10-12. */
@media (max-width:47.99rem){
  .site-header{position:relative}
}

/* NARROW-VIEWPORT SAFETY - nothing may claim an intrinsic width wider than its
   container. Each rule targets a cause, not the element you see spilling out.
   1. A grid track written `1fr` or `auto` is `minmax(auto,1fr)`: its floor is the
      child's min-content, so a wide child pushes the whole track past the container.
      Every `minmax()` floor is therefore capped with `min(<size>,100%)`.
   2. What raises that min-content is almost always one unbreakable token - an email
      address or a URL. `overflow-wrap:anywhere` lowers a box's min-content
      contribution; `break-word` does NOT, which is why it is not used there.
   3. Flex items default to `min-width:auto`, so the header bar cannot shrink below the
      sum of its children's minimums. Rather than force the document wider it now wraps -
      but only when it truly has to. See the mobile block below for how. */
/* Headings, labels and links joined this list on 2026-10-12: at 200% text one long word
   in a heading ("Tub-to-shower", "information") pushed a phone page 30 to 90 px wide. */
p,li,dd,address,blockquote,figcaption,h1,h2,h3,label,a{overflow-wrap:anywhere}
/* ...but never on navigation. A nav label is one or two short words and must stay whole;
   `anywhere` would hyphen-lessly split "Home" into "Ho/me" the moment the bar gets tight. */
.site-nav li,.site-nav a{overflow-wrap:normal}
/* ...nor on a header control. The header bar reads each control's min-content, and
   `anywhere` would let it squeeze "Call" into "Ca/ll". */
.header-bar .btn,.header-phone,.nav-toggle{overflow-wrap:normal}
/* The wordmark gets `break-word`, NOT `anywhere`. `anywhere` would drop its min-content to
   a single character - and min-content is exactly what the header's line-breaking reads
   below, so the bar would stack the business name into a one-letter column. `break-word`
   still breaks a pathologically long name rather than letting it spill; it just does not
   lie about the name's intrinsic width. */
.wordmark{overflow-wrap:break-word}
/* Cards and form fields are often grid items, whose floor is their min-content. A date
   input or a textarea at 200% text has a wide intrinsic size, and it pushed the
   stay-play inquiry card to 518 px on a 375 px phone. Both may shrink; the controls
   inside are width:100%. */
.card,.field{min-width:0}

/* At every width the header bar wraps rather than push the page sideways: at 200%
   text the desktop bar used to run to 1381 px on a 1280 px screen. A bar that fits
   on one row is unchanged. */
.header-bar{flex-wrap:wrap}

/* THE MOBILE HEADER BAR. Scoped to the breakpoint every template already switches its
   header at, so the desktop bar is left exactly as it was - it never overflowed.
   Flex line-breaking reads each item's HYPOTHETICAL main size, not its minimum, so
   `flex-wrap:wrap` alone breaks the bar the moment the wordmark's FULL width stops
   fitting - far earlier than necessary, and on templates that were never in trouble.
   Giving the wordmark a min-content basis makes the break happen on the real minimums:
   the bar stays one row for as long as it genuinely can. */
@media (max-width:47.99rem){
  .header-bar{flex-wrap:wrap}
  /* last-resort backstop for a single child wider than the whole bar */
  .header-bar>*{min-width:0}
  /* No max-width here: the wordmark's min-content basis already lets it wrap. */
  .header-bar>.wordmark{flex:1 1 min-content}
  /* The CTA takes its minimum and does not compete for the spare pixels: on a phone there
     are few of them and they are worth more to the business name than to a button that
     reads fine on two lines. */
  .header-bar>.btn{flex:0 1 min-content}
  /* Menu goes to the end of whichever row it lands on, so a wrapped bar reads as two
     deliberate rows - identity left, controls stacked right - instead of leaving it
     orphaned bottom-left. On an unwrapped row the wordmark's growth has already taken the
     free space, so this auto margin resolves to zero and nothing moves. */
  .header-bar>.nav-toggle{margin-inline-start:auto}
}
/* Wide phones and small tablets have real spare width, so the CTA is allowed to grow back
   to its natural width - capped there, never stretched - instead of sitting on two lines
   all the way up to the desktop breakpoint. */
@media (min-width:36rem) and (max-width:47.99rem){
  .header-bar>.btn{flex-grow:1;max-width:max-content}
}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
  html{scroll-behavior:auto}
}
