/* ==========================================================================
   Wolf Dynasty Fitness: site styles
   Socoz CMS v3.1 fork. Architecture inherited, design written from zero.
   Design approved 2026-07-19.

   RULES, in force everywhere in this file:
     - Flat colors only. No gradients, ever.
     - Hard corners. No border-radius anywhere.
     - No drop shadows and no hard offset shadows. Depth comes from
       rules, hairlines and flat color steps.
     - Violet is rationed: numerals, rules, active states, one solid CTA
       per view. Never a decorative fill.
     - Hover DARKENS. This is a light ground; lightening a fill on hover
       destroys the label contrast on the solid button.
     - The stamp voice (--font-stamp) is Archivo 700, tracked wide. The traced
       wall lettering is the ONLY display exception on the page.
     - Nothing here may echo the sibling gym site this was forked from:
       no navy, no gold, no Bebas/Barlow, no knurl strips, no chamfered
       clip-path corners, no skewed slabs, no angled section edges,
       no grayscale-to-color hover, no ghost/outline type.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Fonts (self-hosted, latin subset, no external requests)
   -------------------------------------------------------------------------- */
/* Display face: ARCHIVO BLACK (chosen 2026-07-30).
   Chosen to SUPPORT the wall mark, not to imitate it. The traced lettering is
   condensed and italic, so the supporting face contrasts on both axes: wide
   and upright. It is also the same superfamily as the body text, so the whole
   page shares one skeleton and the hand-painted mark is the only exception.
   Swappable FILE. To change it:
     cp assets/fonts/cand-<name>.woff2 assets/fonts/wolf-display.woff2
   Nothing else changes. Candidates live alongside it as cand-*.woff2. */
@font-face { font-family: 'Wolf Display';     font-style: normal; font-weight: 400; font-display: swap; src: url('/assets/fonts/wolf-display.woff2') format('woff2'); }
@font-face { font-family: 'Archivo';          font-style: normal; font-weight: 400; font-display: swap; src: url('/assets/fonts/archivo-400.woff2') format('woff2'); }
@font-face { font-family: 'Archivo';          font-style: normal; font-weight: 700; font-display: swap; src: url('/assets/fonts/archivo-700.woff2') format('woff2'); }

/* --------------------------------------------------------------------------
   2. Tokens
   Contrast (computed 2026-08-08 against the brightened violet ramp, all AA):
     ON --violet (#7C3AED, the featured card): concrete-0 5.05 is the ONLY
     safe text colour. concrete-1 is 4.40 and concrete-2 is 3.66, both fail,
     so that card separates its secondary copy by size and weight, not tint.
     ON --violet-band (#5B21B6): concrete-0 7.95, concrete-2 5.77, both pass.
     ink/concrete-0 15.94  ink/concrete-1 13.91  ink/concrete-3  8.71
     violet-ink/concrete-0 6.29  violet-ink/concrete-1 5.49  violet-ink/concrete-2 4.57
     ink-2/concrete-1 6.93  ink-2/concrete-2 5.77
   Dark-ground pairs: violet-lift/ink 6.62, concrete-0/ink 15.9, concrete-3/ink 8.71.
   --ink-2 is the tightest light pair. Do not lighten it, and do not introduce
   a fourth grey below it for captions or placeholders.
   -------------------------------------------------------------------------- */
:root {
  color-scheme: light;

  --concrete-0: #F2F1EE;   /* plates, form fields, inverted type */
  --concrete-1: #E4E2DD;   /* PAGE GROUND */
  --concrete-2: #D2CFC8;   /* alternating band */
  --concrete-3: #B8B4AB;   /* deep band, empty-plate fill */

  --ink:        #17161A;   /* headlines and body */
  --ink-2:      #4A4852;   /* secondary copy */

  /* Violet ramp, brightened 2026-08-08 at the client's call ("I like the
     brighter purple, especially now with the colour photos"). The dusty
     #4B3A73 was tuned to carry a black-and-white page; against colour
     photography it went muddy. This is the Tailwind violet family, kept as a
     RAMP because one brightness cannot do all four jobs at AA:
       --violet      fills and structure. concrete-0 on it is 5.05:1 AA.
       --violet-ink  violet used as TEXT on light grounds. The bright violet
                     is only 4.40:1 on the page ground, so text steps down
                     one stop to 5.49:1. Never use --violet for small text.
       --violet-deep hover and pressed. Must stay DARKER than --violet.
       --violet-lift violet TEXT on ink grounds: 6.62:1.
       --violet-band the full-bleed creed band ONLY. The bright violet is
                     right on a button or a card, but across a whole viewport
                     it stops being an accent and becomes the page: it
                     outweighed the ink and concrete fields and changed the
                     site's balance. One step down keeps the same hue family
                     at a weight the layout was built for, and it restores
                     concrete-2 (5.77:1) as usable secondary text on it. */
  --violet:     #7C3AED;   /* fills, rules, CTA, focus, selection */
  --violet-band:#5B21B6;   /* the ONE full-bleed field. See note below. */
  --violet-ink: #6D28D9;   /* violet as TEXT on concrete grounds */
  --violet-deep:#4C1D95;   /* hover and pressed */
  --violet-lift:#A78BFA;   /* violet FOR TEXT ON DARK grounds: 6.62:1 on ink.
                              --violet on ink is 3.16:1, large/decorative only. */

  --hairline:   rgba(23, 22, 26, .16);
  --rule-w:     4px;

  --font-display: 'Wolf Display', 'Arial Black', sans-serif;
  --font-body:    'Archivo', 'Helvetica Neue', Arial, sans-serif;
  /* Stamp voice: the stencil face was retired at the client's call (2026-08-06,
     "not loving the military stencil style"). Stamps are now the body family
     at 700, tracked wide: one family across the whole site, the traced wall
     lettering stays the only display exception. */
  --font-stamp:   'Archivo', 'Helvetica Neue', Arial, sans-serif;

  /* Motion. One easing curve for the whole site: an ease-out-expo that
     decelerates hard, so reveals arrive rather than drift. No bounce.
     Every rule using these has a prefers-reduced-motion answer at the
     bottom of this file. */
  --ease:     cubic-bezier(.16, 1, .3, 1);
  --dur-fast: .22s;
  --dur-med:  .45s;
  --dur-slow: .7s;

  /* The one grade applied to every photograph on the page. Light on purpose:
     the shoot is warm and the gym interior is dark, so a heavier saturate()
     turns the red plates garish against the violet. */
  --photo-filter: saturate(1.08) contrast(1.06) brightness(1.02);

  --bay:  1240px;
  --pad:  clamp(20px, 5vw, 40px);
  --band: clamp(64px, 9vw, 128px);
}

/* --------------------------------------------------------------------------
   3. Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; scroll-padding-top: 88px; -webkit-text-size-adjust: 100%; }

body {
  background: var(--concrete-1);
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 17px;
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }
a   { color: inherit; }
button, input, select, textarea { font: inherit; color: inherit; }

::selection { background: var(--violet); color: var(--concrete-0); }

/* Focus. The override is load-bearing: a violet ring on the violet button
   is invisible at 1:1. Concrete on violet is 9.76:1. */
:focus-visible { outline: 3px solid var(--violet); outline-offset: 3px; }
.btn--solid:focus-visible,
.summon .btn--solid:focus-visible { outline-color: var(--concrete-0); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--ink); color: var(--concrete-0); padding: 12px 20px;
  font-family: var(--font-body); font-weight: 700;
}
.skip:focus { left: 0; }

/* --------------------------------------------------------------------------
   4. Grounds
   FLAT. The generated concrete texture was removed 2026-07-20 at the client's
   direction (it read as noise and muddied the text). Do not reintroduce noise,
   grain, or texture layers anywhere: color fields are flat, photography is the
   only texture this site has. The page is a near 50/50 mix of light concrete
   and ink, with violet carrying full bands and key blocks, not just accents.
   -------------------------------------------------------------------------- */
/* Announcement banner. The admin can switch this on at any time and it had no
   CSS whatsoever, so it rendered as unstyled body text jammed above the
   masthead. It sits ABOVE the sticky header in the DOM, so it scrolls away
   rather than competing with the nav. */
.announcement {
  background: var(--violet-band);
  color: var(--concrete-0);
  font-size: .92rem;
  line-height: 1.45;
  padding: 10px var(--pad);
  text-align: center;
}
.announcement a { color: var(--concrete-0); text-decoration: underline; text-underline-offset: 3px; }
.announcement a:hover { text-decoration-thickness: 2px; }

.slab--pale   { background-color: var(--concrete-0); }
.slab--deep   { background-color: var(--concrete-2); }
.slab--ink    { background-color: var(--ink); }
.slab--violet { background-color: var(--violet-band); color: var(--concrete-0); }

/* --------------------------------------------------------------------------
   5. Layout primitives
   -------------------------------------------------------------------------- */
.bay        { width: 100%; max-width: var(--bay); margin: 0 auto; padding: 0 var(--pad); }
.bay--tight { max-width: 760px; }

.slab        { padding: var(--band) 0; }
.slab--ink   { color: var(--concrete-0); }
.slab--flush { padding: 0; }

/* --------------------------------------------------------------------------
   6. Type primitives
   -------------------------------------------------------------------------- */
.stamp {
  font-family: var(--font-stamp);
  font-weight: 700;
  font-size: .8rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--violet-ink);
  display: block;
  margin-bottom: 14px;
}
.slab--ink .stamp,
.poster .stamp { color: var(--violet-lift); }
.slab--violet .stamp { color: var(--concrete-2); }

.rule {
  width: 128px; height: 6px;
  background: var(--violet);
  margin: 22px 0 26px;
}
.slab--ink .rule,
.poster .rule { background: var(--violet-lift); }
.slab--violet .rule { background: var(--concrete-0); }

.blockhead            { max-width: 780px; margin-bottom: 48px; }
.blockhead__title {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 4.2vw, 3.1rem);
  line-height: 1.02;
  letter-spacing: -.015em;
  text-transform: uppercase;
}
.blockhead__lede { margin-top: 18px; color: var(--ink-2); max-width: 62ch; font-size: 1.05rem; }
.slab--ink .blockhead__lede { color: var(--concrete-3); }

/* --------------------------------------------------------------------------
   7. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 15px 30px;
  font-family: var(--font-body); font-weight: 700;
  font-size: .84rem; letter-spacing: .1em; text-transform: uppercase;
  border: 2px solid transparent; cursor: pointer;
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.btn--solid   { background: var(--violet); color: var(--concrete-0); border-color: var(--violet); }
.btn--solid:hover { background: var(--violet-deep); border-color: var(--violet-deep); }

.btn--outline { background: transparent; color: var(--ink); border-color: var(--ink); }
.poster .btn--outline { color: var(--concrete-0); border-color: var(--concrete-0); }
.poster .btn--outline:hover { background: var(--concrete-0); color: var(--ink); }
.btn--outline:hover { background: var(--ink); color: var(--concrete-0); }
.slab--ink .btn--outline { color: var(--concrete-0); border-color: var(--concrete-0); }
.slab--ink .btn--outline:hover { background: var(--concrete-0); color: var(--ink); }

.btn--text {
  padding: 0; border: 0; color: var(--violet-ink);
  border-bottom: 2px solid var(--violet); padding-bottom: 3px;
}
.btn--text:hover { color: var(--violet-deep); border-color: var(--violet-deep); }

/* --------------------------------------------------------------------------
   8. Masthead
   -------------------------------------------------------------------------- */
.mast {
  position: sticky; top: 0; z-index: 50;
  background-color: var(--concrete-0);
  border-bottom: 2px solid var(--ink);
}
.mast__inner {
  max-width: var(--bay); margin: 0 auto; padding: 0 var(--pad);
  height: 84px; display: flex; align-items: center; justify-content: space-between; gap: 24px;
}
.mast__lockup { display: flex; align-items: center; gap: 12px; text-decoration: none; }
.mast__logo   { height: 48px; width: auto; display: block; }
/* Wordmark is the shipping lockup until real logo artwork arrives. */
.mast__wordmark {
  font-family: var(--font-display);
  font-size: 1.28rem; letter-spacing: -.01em; text-transform: uppercase; line-height: 1;
}
.mast__wordmark span { font-family: var(--font-stamp); font-weight: 700; color: var(--violet-ink); letter-spacing: .06em; }

.mast__nav  { display: flex; align-items: center; gap: 30px; list-style: none; }
.mast__nav a {
  font-weight: 700; font-size: .82rem; letter-spacing: .08em; text-transform: uppercase;
  text-decoration: none; padding: 6px 0; border-bottom: 2px solid transparent;
  transition: border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.mast__nav a:hover              { border-color: var(--ink); }
.mast__nav a[aria-current]      { border-color: var(--violet); color: var(--violet-ink); }

.mast__toggle { display: none; background: none; border: 2px solid var(--ink); padding: 10px 12px; cursor: pointer; }
.mast__toggle span { display: block; width: 22px; height: 2px; background: var(--ink); }
.mast__toggle span + span { margin-top: 5px; }

.mast__drawer { display: none; }

/* --------------------------------------------------------------------------
   9. HERO: "The Pack"
   A pinned ink panel carries the wall lettering while full-size photographs
   scroll past it. Copy never touches photography (concrete on ink, 15.9:1,
   a constant), the photo is never reduced to a strip on any breakpoint, and
   the motion is the visitor's own scroll: no timers, nothing to pause.
   position:sticky only; works in every browser.
   -------------------------------------------------------------------------- */
.poster {
  position: relative;
  background-color: var(--ink);
  color: var(--concrete-0);
}
.poster__grid {
  display: grid;
  grid-template-columns: 38% 62%;
}
.poster__panel { position: relative; z-index: 5; background: var(--ink); }
.poster__panel-inner {
  position: sticky;
  top: 84px;                       /* below the sticky masthead */
  min-height: calc(100svh - 84px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(28px, 4vw, 56px);
}
.poster__h1 { margin: 18px 0 0; line-height: 0; }
.poster__h1 svg { display: block; width: 100%; max-width: 460px; height: auto; color: var(--concrete-0); }

.poster__shots { border-left: 8px solid var(--violet); min-width: 0; }
.poster__shot {
  position: relative;
  margin: 0;
  height: 88svh;
  overflow: hidden;
}
.poster__shot + .poster__shot { border-top: 8px solid var(--violet); }
/* Photography runs in FULL COLOUR (client call, 2026-08-08: the black and
   white read as "gray washed"). Five images had grayscale baked into the webp
   by the old pipeline and were re-encoded from source at identical crops; do
   not "fix" a gray-looking photo in CSS, check the file first.
   The slow scale is the "pop": the frame is fixed and the photograph drifts
   inside it, so nothing reflows and the crop never breaks. */
.poster__shot img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: var(--photo-filter);
  transform: scale(1.001);           /* promotes the layer, kills the 1px seam */
  transition: transform var(--dur-slow) var(--ease);
}
.poster__shot:hover img { transform: scale(1.04); }
.poster__cap {
  position: absolute; left: 0; bottom: 0;
  background: var(--ink); color: var(--concrete-0);
  font-family: var(--font-stamp); font-weight: 700; font-size: .72rem;
  letter-spacing: .16em; text-transform: uppercase;
  padding: 8px 16px;
}

.poster__tag {
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 1.6vw, 1.5rem);
  line-height: 1.08;
  letter-spacing: -.015em;
  text-transform: uppercase;
  color: var(--concrete-0);
  margin-top: 22px;
}
/* The violet sentence gets its own line: split mid-line, the color change
   reads as a wrap accident instead of a deliberate second voice. */
.poster__tag em { display: block; font-style: normal; color: var(--violet-lift); }

.poster__acts { margin-top: 34px; display: flex; flex-wrap: wrap; gap: 14px; }

.poster__meta {
  position: relative; z-index: 6;
  margin-top: 0; padding-top: 26px; padding-bottom: clamp(22px, 3vh, 40px);
  border-top: 2px solid var(--violet);
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px;
}
.poster__meta div  { border-left: 1px solid rgba(242,241,238,.18); padding-left: 18px; }
.poster__meta div:first-child { border-left: 0; padding-left: 0; }
.poster__meta b    { display: block; color: var(--concrete-0); font-family: var(--font-body); font-weight: 700; font-size: .98rem; text-transform: uppercase; letter-spacing: -.01em; }
.poster__meta span { display: block; margin-top: 4px; font-size: .84rem; color: var(--concrete-3); }

/* --------------------------------------------------------------------------
   10. Blockshot (hard-edged photography, full colour since 2026-08-08)
   No hover-to-color: that belongs to the sibling site.
   .blockshot--empty is a DESIGNED state, not a dashed placeholder box, so the
   site can launch before the photo shoot happens.
   -------------------------------------------------------------------------- */
.blockshot { position: relative; overflow: hidden; background-color: var(--concrete-3); }
.blockshot img {
  width: 100%; height: 100%; object-fit: cover;
  filter: var(--photo-filter);
  transform: scale(1.001);
  transition: transform var(--dur-slow) var(--ease);
}
.blockshot:hover img,
.blockshot:focus-within img { transform: scale(1.04); }
/* Baked print grain over the image. */
/* No grain overlay: real photography needs no fake film. */
.blockshot--wide  { aspect-ratio: 21 / 9; }
.blockshot--tall  { aspect-ratio: 4 / 5; }

.blockshot--empty { display: grid; place-items: center; }
.blockshot--empty .blockshot__mark {
  font-family: var(--font-stamp);
  font-weight: 700;
  font-size: clamp(1rem, 2.6vw, 1.6rem);
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--ink); opacity: .34; text-align: center; padding: 0 20px;
}
.blockshot__cap {
  position: absolute; left: 0; bottom: 0;
  background: var(--ink); color: var(--concrete-0);
  font-family: var(--font-stamp); font-weight: 700; font-size: .72rem;
  letter-spacing: .16em; text-transform: uppercase;
  padding: 8px 16px;
}

/* --------------------------------------------------------------------------
   11. Creed (the one dark moment on the page)
   -------------------------------------------------------------------------- */
.creed__line {
  font-family: var(--font-display);
  font-size: clamp(1.8rem, 5.4vw, 4.2rem);
  line-height: 1.0; letter-spacing: -.02em; text-transform: uppercase;
  max-width: 20ch;
}
.creed__attr { margin-top: 28px; font-size: .88rem; letter-spacing: .1em; text-transform: uppercase; color: var(--concrete-3); }
.slab--violet .creed__line { color: var(--concrete-0); }
.creed__word { display: block; width: clamp(180px, 22vw, 300px); height: auto; margin-bottom: 20px; }
.slab--violet .creed__attr { color: var(--concrete-2); }

/* --------------------------------------------------------------------------
   12. Marklist (square ink bullets, no checkmark glyphs)
   -------------------------------------------------------------------------- */
.marklist { list-style: none; }
.marklist li { position: relative; padding-left: 26px; margin-bottom: 16px; }
.marklist li::before {
  content: ''; position: absolute; left: 0; top: .55em;
  width: 9px; height: 9px; background: var(--violet);
}
.marklist b { display: block; font-family: var(--font-body); font-weight: 700; font-size: .96rem; text-transform: uppercase; letter-spacing: -.01em; margin-bottom: 3px; }
.marklist p { color: var(--ink-2); font-size: .95rem; }

/* --------------------------------------------------------------------------
   13. Den (facility): a list and a picture, not a card grid
   -------------------------------------------------------------------------- */
.den__grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(32px, 5vw, 72px); align-items: start; }

/* --------------------------------------------------------------------------
   14. Ledger (hairline index rows, used for events)
   -------------------------------------------------------------------------- */
.ledger { border-top: 2px solid var(--ink); }
.slab--ink .ledger { border-top-color: var(--concrete-0); }
.slab--ink .ledger__row { border-bottom-color: rgba(242,241,238,.14); }
.slab--ink .ledger__ttl { color: var(--concrete-0); }
.slab--ink .ledger__txt { color: var(--concrete-3); }
.slab--ink .blockhead__lede { color: var(--concrete-3); }
.ledger__row {
  padding: 26px 0; border-bottom: 1px solid var(--hairline);
}
.ledger__ttl { font-family: var(--font-display); font-size: 1.22rem; text-transform: uppercase; letter-spacing: -.01em; margin-bottom: 6px; }
.ledger__txt { color: var(--ink-2); font-size: .96rem; max-width: 64ch; }

/* --------------------------------------------------------------------------
   15. Tiers (membership)
   -------------------------------------------------------------------------- */
.tiers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.tier {
  background-color: var(--concrete-0);
  border: 1px solid var(--hairline);
  padding: 34px 28px;
  display: flex; flex-direction: column;
}
.tier--featured { background-color: var(--violet); border: 2px solid var(--violet); color: var(--concrete-0); }
.tier--featured .tier__name,
.tier--featured .tier__amount { color: var(--concrete-0); }
/* concrete-2 on the bright violet is 3.66:1 and fails AA, so this card's
   secondary copy stays concrete-0 and steps down by size/weight instead. */
.tier--featured .tier__desc,
.tier--featured .tier__period,
.tier--featured .tier__feats li { color: var(--concrete-0); }
.tier--featured .tier__feats li::before { background: var(--violet-lift); }
.tier--featured .tier__badge { background: var(--concrete-0); color: var(--violet-deep); }
/* Ink-on-violet fails contrast (1.85:1), so the featured CTA is a paper button. */
.tier--featured .btn--solid { background: var(--concrete-0); color: var(--ink); border-color: var(--concrete-0); }
.tier--featured .btn--solid:hover { background: var(--concrete-2); border-color: var(--concrete-2); }
.tier--featured .btn--solid:focus-visible { outline-color: var(--concrete-0); }
.tier__badge {
  align-self: flex-start;
  font-family: var(--font-stamp); font-weight: 700; font-size: .7rem; letter-spacing: .16em; text-transform: uppercase;
  background: var(--ink); color: var(--concrete-0); padding: 5px 12px; margin-bottom: 16px;
}
.tier__name { font-family: var(--font-display); font-size: 1.32rem; text-transform: uppercase; letter-spacing: -.01em; }
.tier__desc { margin-top: 10px; color: var(--ink-2); font-size: .95rem; }
.tier__price { margin: 24px 0 22px; display: flex; align-items: baseline; gap: 5px; }
.tier__amount { font-family: var(--font-display); font-size: 2.7rem; line-height: 1; letter-spacing: -.02em; }
.tier__amount--word { font-size: 1.7rem; }
.tier__period { color: var(--ink-2); font-size: .9rem; }
.tier__feats { list-style: none; margin-bottom: 26px; }
.tier__feats li { position: relative; padding-left: 22px; padding-bottom: 9px; font-size: .94rem; color: var(--ink-2); }
.tier__feats li::before { content: ''; position: absolute; left: 0; top: .58em; width: 7px; height: 7px; background: var(--violet); }
.tier__cta { margin-top: auto; justify-content: center; }
.tiers__note { margin-top: 26px; font-size: .9rem; color: var(--ink-2); }

/* --------------------------------------------------------------------------
   16. Word (single testimonial, deliberately not a three-card grid)
   -------------------------------------------------------------------------- */
.word__quote {
  font-size: clamp(1.25rem, 2.9vw, 2rem);
  line-height: 1.32; font-weight: 400; max-width: 24ch;
  border-left: 6px solid var(--violet); padding-left: 26px;
}
.word__attr { margin-top: 22px; padding-left: 30px; font-size: .86rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2); }

/* --------------------------------------------------------------------------
   17. Summon (closing CTA)
   -------------------------------------------------------------------------- */
.summon      { text-align: center; }
.summon__ttl { font-family: var(--font-display); font-size: clamp(1.7rem, 4.6vw, 3rem); text-transform: uppercase; letter-spacing: -.02em; line-height: 1.04; }
.summon__sub { margin: 16px auto 30px; color: var(--ink-2); max-width: 48ch; }

/* --------------------------------------------------------------------------
   18. Hours + dispatch (contact)
   -------------------------------------------------------------------------- */
.hours { border-top: 2px solid var(--ink); max-width: 460px; }
.hours__row {
  display: flex; justify-content: space-between; gap: 16px;
  padding: 13px 0; border-bottom: 1px solid var(--hairline); font-size: .96rem;
}
.hours__row[data-today] { color: var(--violet-ink); font-weight: 700; }
.hours__row[data-today] .hours__day::before { content: '\2022\00a0'; }
.hours__note { margin-top: 14px; font-size: .9rem; color: var(--ink-2); max-width: 42ch; }

.dispatch__grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px, 5vw, 72px); align-items: start; }
.info { list-style: none; }
.info li { padding: 16px 0; border-bottom: 1px solid var(--hairline); }
.info h5 { font-family: var(--font-stamp); font-weight: 700; font-size: .72rem; letter-spacing: .16em; text-transform: uppercase; color: var(--violet-ink); margin-bottom: 5px; }
.info a  { text-decoration: none; border-bottom: 1px solid var(--hairline); }
.info a:hover { border-color: var(--ink); }
.info__phone { font-family: var(--font-body); font-weight: 700; font-size: 1.35rem; letter-spacing: -.01em; }

/* --------------------------------------------------------------------------
   19. Forms
   Control borders use --ink-2, which clears 3:1 against every concrete step.
   Placeholder text never goes lighter than --ink-2.
   -------------------------------------------------------------------------- */
.cform { background-color: var(--concrete-0); border: 2px solid var(--ink); padding: clamp(24px, 3.4vw, 38px); }
.fgroup { margin-bottom: 18px; }
.fgroup label {
  display: block; margin-bottom: 7px;
  font-family: var(--font-body); font-weight: 700;
  font-size: .74rem; letter-spacing: .1em; text-transform: uppercase;
}
.fgroup input, .fgroup select, .fgroup textarea {
  width: 100%; padding: 13px 14px;
  background: var(--concrete-0);
  border: 1px solid var(--ink-2);
  font-size: .98rem;
}
.fgroup input::placeholder, .fgroup textarea::placeholder { color: var(--ink-2); opacity: 1; }
.fgroup input:focus, .fgroup select:focus, .fgroup textarea:focus { border-color: var(--violet); }
.fgroup textarea { resize: vertical; min-height: 120px; }
.frow { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form-msg { display: none; margin-top: 16px; padding: 13px 16px; font-size: .93rem; border: 2px solid; }
.form-msg.ok, .form-msg.err { display: block; }
.form-msg.ok  { border-color: var(--ink); background: var(--concrete-1); }
.form-msg.err { border-color: var(--violet); background: var(--concrete-1); color: var(--violet-deep); }

.mapframe { border: 2px solid var(--ink); line-height: 0; }
/* The map stays desaturated even though the photography is now colour: it is
   a Google widget, not a photograph, and its own green/blue/yellow palette
   belongs to Google rather than to this brand. */
.mapframe iframe { width: 100%; height: 340px; border: 0; filter: grayscale(1) contrast(1.08); }

/* --------------------------------------------------------------------------
   20. Footer
   -------------------------------------------------------------------------- */
.foot { background-color: var(--ink); color: var(--concrete-3); padding: clamp(48px, 6vw, 76px) 0 30px; }
.foot__top { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 40px; padding-bottom: 38px; border-bottom: 1px solid rgba(242,241,238,.16); }
.foot__logo { height: 72px; width: auto; margin-bottom: 16px; }
.foot__logo--lockup { height: auto; width: clamp(180px, 16vw, 240px); }
.foot__wordmark { font-family: var(--font-display); font-size: 1.3rem; text-transform: uppercase; color: var(--concrete-0); letter-spacing: -.01em; }
.foot__wordmark span { font-family: var(--font-stamp); font-weight: 700; color: var(--concrete-3); letter-spacing: .06em; }
.foot__tag  { margin-top: 14px; max-width: 42ch; font-size: .93rem; }
.foot h6    { font-family: var(--font-stamp); font-weight: 700; font-size: .74rem; letter-spacing: .16em; text-transform: uppercase; color: var(--concrete-0); margin-bottom: 14px; }
.foot ul    { list-style: none; }
.foot li    { margin-bottom: 9px; font-size: .93rem; }
.foot a     { text-decoration: none; }
.foot a:hover { color: var(--concrete-0); }
.foot__base { padding-top: 22px; display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; font-size: .8rem; }

/* --------------------------------------------------------------------------
   21. Scroll reveal (renamed from the upstream .reveal so no stray rule applies)
   Hidden only when JS is confirmed present, so no-JS users see everything.
   -------------------------------------------------------------------------- */
/* Scroll reveals. Scoped under .js so a visitor without JavaScript gets the
   page fully visible: the reveal enhances a working default, it never gates
   the content on a class that might not arrive.
   --rd staggers siblings (set inline in index.php); .rise--media adds a
   settle-from-slightly-larger so photographs land rather than slide. */
.js .rise        { opacity: 0; transform: translateY(18px); }
.js .rise--media { transform: translateY(12px) scale(1.03); }
.js .rise.in {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
  transition-delay: var(--rd, 0ms);
}

/* --------------------------------------------------------------------------
   22. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1020px) {
  .den__grid, .dispatch__grid, .poster__grid { grid-template-columns: 1fr; }
  /* Same design stacked: the ink panel becomes a compact sticky header card
     and the shots scroll past beneath it. The panel drops its full-viewport
     centering: on a phone it is a masthead, not a column. */
  .poster__panel-inner {
    top: 68px;
    min-height: 0;
    justify-content: flex-start;
    padding: 22px var(--pad) 26px;
  }
  .poster__h1 svg { max-width: 340px; }
  .poster__shots { border-left: 0; border-top: 8px solid var(--violet); }
  .poster__shot { height: 62svh; }
  .tiers { grid-template-columns: 1fr; max-width: 520px; }
  .foot__top { grid-template-columns: 1fr 1fr; }
}

/* The masthead collapses to the drawer at 1130px, NOT at the phone breakpoint.
   Measured on the live page: the wordmark, four nav items and the CTA need
   ~1046px plus padding, so from 721px up to ~1130px they wrapped, the wordmark
   broke onto two lines and "Join the Pack" stacked into three inside a 68px
   bar. That band is every iPad (768/820/834 portrait, 1024/1112/1133
   landscape) and small laptops. Only the header moves this early; the rest of
   the mobile layout stays on the phone breakpoint below. */
@media (max-width: 1130px) {
  html { scroll-padding-top: 72px; }
  .mast__inner { height: 68px; }
  .mast__nav { display: none; }
  .mast__cta { display: none; }
  .mast__toggle { display: block; }
  .mast__drawer { display: none; border-top: 2px solid var(--ink); background: var(--concrete-0); }
  .mast__drawer.open { display: block; padding: 12px var(--pad) 22px; }
  .mast__drawer ul { list-style: none; }
  .mast__drawer li { border-bottom: 1px solid var(--hairline); }
  .mast__drawer a {
    display: block; padding: 15px 0; text-decoration: none;
    font-family: var(--font-display); font-size: 1.05rem; text-transform: uppercase;
  }
  .mast__drawer .btn { margin-top: 18px; width: 100%; justify-content: center; }
}

/* Phone layout. These stack content and must NOT fire on a tablet, where the
   three-up meta bar, the side-by-side form row and the footer columns all
   still fit comfortably. */
@media (max-width: 720px) {
  .poster__meta { grid-template-columns: 1fr; gap: 18px; }
  .poster__meta div { border-left: 0; padding-left: 0; padding-top: 14px; border-top: 1px solid var(--hairline); }
  .poster__meta div:first-child { padding-top: 0; border-top: 0; }

  .blockshot--wide { aspect-ratio: 4 / 3; }
  .frow { grid-template-columns: 1fr; }
  .foot__top { grid-template-columns: 1fr; gap: 30px; }
}

/* --------------------------------------------------------------------------
   23. Reduced motion and print
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
  .js .rise, .js .rise--media { opacity: 1; transform: none; }
  /* The photo drift is motion too: hold every frame still. */
  .poster__shot img, .blockshot img,
  .poster__shot:hover img, .blockshot:hover img, .blockshot:focus-within img { transform: none; }
}

@media print {
  .mast, .foot, .aggregate, .btn { display: none; }
  body { background: #fff; color: #000; }
}
