/* ===========================================================================
   LATCHFORD — DESIGN LAYER
   Owner of the colour VALUES: site-build-spec-woocommerce.md Section 6.0.
   This file spends them; it does not define new ones.

   THE ACCENT RULE, CORRECTED 07-Sep-2026 AND THE OLD VERSION WAS A DEFECT.
   Bronze #A17236 measures 4.22:1 on white, 3.90 on surface, 4.38 on the dark
   panel. Body text needs 4.5:1. So bronze FAILS as text on every ground this
   site uses, and the previous build had it set as 11px eyebrow text, which
   broke rule B4 in the file that declares rule B4.
     - BRONZE IS GRAPHIC ONLY: rules, borders, hover marks, solid blocks.
       Never a letterform. Contrast ratios do not govern a 2px rule.
     - BRONZE NEVER APPEARS ON A DARK GROUND. Owner's instruction, and it is
       right on its own terms: a muted metallic goes muddy on near-black.
     - ON DARK the palette is white and #9AA3AA only (7.22:1).
   Dark grounds earn their interest from the DRAWINGS, not from colour.
   =========================================================================== */

@font-face {
  font-family: 'Archivo';
  src: url('fonts/archivo-latin-var.woff2') format('woff2-variations');
  font-weight: 100 900; font-style: normal; font-display: swap;
  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+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

html:root {
  --latch-font: 'Archivo', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --theme-font-family: var(--latch-font);

  --fs-eyebrow: 0.6875rem;
  --fs-small:   0.875rem;
  --fs-body:    1.0625rem;
  --fs-lead:    clamp(1.0625rem, 0.95rem + 0.45vw, 1.1875rem);
  --fs-h3:      clamp(1.0625rem, 1rem + 0.35vw, 1.1875rem);
  --fs-h2:      clamp(1.5rem,   1.2rem + 1.25vw, 2.25rem);
  --fs-h1:      clamp(2rem,     1.45rem + 2.6vw, 3.5rem);

  --sec-y:  clamp(3rem, 2.2rem + 3.2vw, 5rem);
  --gutter: clamp(1.25rem, 1rem + 1.5vw, 2rem);
  --maxw:   1200px;
}

body, .entry-content { font-family: var(--latch-font); font-size: var(--fs-body); line-height: 1.62; }
h1, h2, h3, h4 { font-family: var(--latch-font); letter-spacing: -0.022em; line-height: 1.1; }

/* ---------------------------------------------------------------- SECTIONS */
.lx { padding-block: var(--sec-y); }
.lx--flush { padding-block: 0; }
.lx--tint { background: var(--latch-surface); }
.lx--dark { background: var(--latch-panel); color: var(--latch-panel-text); }
.lx-wrap { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }

/* Full bleed. Blocksy caps every direct child of .entry-content at 1290px, so
   max-width must be cleared as well as the margins pulled. width stays auto
   because #main-container is overflow-x:clip and 100vw would overhang. */
.entry-content > .lx {
  max-width: none; width: auto;
  margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw);
}

/* EYEBROW. Text is steel (5.86:1) or muted grey on dark (7.22:1), never
   bronze. The RULE beside it is bronze, which is where the accent belongs. */
.lx-eyebrow {
  display: flex; align-items: center; gap: .75rem; margin: 0 0 .9rem;
  font-size: var(--fs-eyebrow); font-weight: 700; letter-spacing: .15em;
  text-transform: uppercase; color: var(--latch-steel);
}
.lx-eyebrow::before { content: ""; width: 26px; height: 2px; background: var(--latch-bronze); flex: none; }
.lx-eyebrow--onDark { color: var(--latch-panel-muted); }
.lx-eyebrow--onDark::before { background: var(--latch-panel-muted); }

.lx-h2 { font-size: var(--fs-h2); font-weight: 800; margin: 0 0 .75rem; max-width: 22ch; }
.lx-h2--onDark { color: #fff; }
.lx-lead { font-size: var(--fs-lead); color: var(--latch-steel); max-width: 58ch; margin: 0 0 2rem; }

/* -------------------------------------------------------------------- HERO */
.lx-hero { padding-block: clamp(3rem, 2rem + 4.5vw, 5.5rem); }
.lx-hero__grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
.lx-hero h1 { font-size: var(--fs-h1); font-weight: 800; color: #fff; max-width: 15ch; margin: 0 0 1.1rem; }
.lx-hero__sub { color: var(--latch-panel-muted); font-size: var(--fs-lead); max-width: 52ch; margin: 0 0 2rem; }
.lx-hero__art { display: flex; justify-content: center; }
.lx-split { display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(2rem, 5vw, 4rem); align-items: center; }
.lx-split__art { display: flex; justify-content: center; }
.lx--closing .lx-h2 { max-width: 24ch; }

/* ---------------------------------------------------------------- DRAWINGS */
.latch-art { width: 100%; height: auto; display: block; color: inherit; }
.latch-art--hero { max-width: 460px; opacity: .95; }

/* ------------------------------------------------------------ CAPABILITIES */
.lx-caps { display: grid; grid-template-columns: repeat(4, 1fr); border-bottom: 1px solid var(--latch-line); }
.lx-cap { padding: 1.5rem 1.5rem 1.5rem 0; border-top: 3px solid var(--latch-bronze); margin-right: 1px; }
.lx-cap + .lx-cap { padding-left: 1.5rem; }
.lx-cap__k { display: block; font-weight: 700; font-size: var(--fs-small); margin-bottom: .15rem; }
.lx-cap__v { display: block; font-size: var(--fs-small); color: var(--latch-steel); }

/* --------------------------------------------------------------- CARD GRID */
.lx-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--latch-line); border: 1px solid var(--latch-line); }
.lx-card {
  background: #fff; padding: 1.5rem 1.35rem 1.6rem; display: flex; flex-direction: column;
  text-decoration: none !important; color: inherit; position: relative; min-width: 0;
  transition: background-color .16s ease;
}
.lx-card::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 3px;
  background: var(--latch-bronze); transform: scaleX(0); transform-origin: left;
  transition: transform .18s ease;
}
.lx-card:hover { background: var(--latch-surface); }
.lx-card:hover::after { transform: scaleX(1); }
.lx-card__art { display: block; color: var(--latch-ink); margin-bottom: 1.1rem; }
.lx-card__art .latch-art { max-width: 150px; }
.lx-card__t { display: block; font-size: var(--fs-h3); font-weight: 700; letter-spacing: -.012em; margin-bottom: .3rem; }
.lx-card__d { display: block; font-size: var(--fs-small); color: var(--latch-steel); line-height: 1.5; }

/* ------------------------------------------------------------------- CHIPS */
.lx-chips { display: flex; flex-wrap: wrap; gap: .5rem; margin: 1.4rem 0 1.5rem; padding: 0; list-style: none; }
.lx-chips li {
  border: 1px solid var(--latch-line); border-bottom: 2px solid var(--latch-bronze);
  background: #fff; padding: .6rem 1.05rem; font-weight: 600; font-size: var(--fs-small);
}
.lx-note { border-left: 2px solid var(--latch-bronze); padding-left: 1.1rem; color: var(--latch-steel); font-size: var(--fs-small); max-width: 68ch; margin: 0 0 1.6rem; }

/* ------------------------------------------------------------------- STEPS */
.lx-steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(1.25rem, 3vw, 2.25rem); list-style: none; margin: 2rem 0 0; padding: 0; }
.lx-step { padding-top: 1.1rem; border-top: 3px solid var(--latch-bronze); }
.lx-step__n { display: block; font-size: 0.75rem; font-weight: 700; letter-spacing: .16em; color: var(--latch-steel); margin-bottom: .7rem; }
.lx-step__t { display: block; font-size: var(--fs-h3); font-weight: 700; margin-bottom: .3rem; }
.lx-step__d { display: block; font-size: var(--fs-small); color: var(--latch-steel); line-height: 1.5; }

/* --------------------------------------------------------------------- FAQ */
.lx-faq { border-top: 1px solid var(--latch-line); margin-top: 1.6rem; }
.lx-faq__row { border-bottom: 1px solid var(--latch-line); padding: 1.4rem 0; display: grid; grid-template-columns: minmax(0, 21rem) 1fr; gap: clamp(1rem, 3vw, 2.5rem); }
.lx-faq__q { font-size: var(--fs-h3); font-weight: 700; margin: 0; }
.lx-faq__a { margin: 0; color: var(--latch-steel); font-size: var(--fs-small); max-width: 64ch; line-height: 1.6; }

/* ----------------------------------------------------------------- BUTTONS */
.lx-actions { display: flex; flex-wrap: wrap; gap: .75rem; margin: 0; }
.lx-btn {
  display: inline-flex; align-items: center; font: inherit; font-weight: 600;
  font-size: var(--fs-small); padding: .82rem 1.4rem; border-radius: 2px;
  border: 1px solid transparent; text-decoration: none !important; cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.lx-btn--ink     { background: var(--latch-ink); color: #fff; border-color: var(--latch-ink); }
.lx-btn--ink:hover { background: #000; border-color: #000; color: #fff; }
.lx-btn--light   { background: #fff; color: var(--latch-ink); border-color: #fff; }
.lx-btn--light:hover { background: var(--latch-line); border-color: var(--latch-line); color: var(--latch-ink); }
.lx-btn--ghost   { background: transparent; color: #fff; border-color: rgba(255,255,255,.45); }
.lx-btn--ghost:hover { border-color: #fff; background: rgba(255,255,255,.08); color: #fff; }
.lx-btn--outline { background: #fff; color: var(--latch-ink); border-color: var(--latch-control); }
.lx-btn--outline:hover { border-color: var(--latch-ink); background: var(--latch-surface); }

/* ------------------------------------------------------------ RESPONSIVE */
@media (max-width: 1080px) {
  .lx-grid  { grid-template-columns: repeat(2, 1fr); }
  .lx-caps  { grid-template-columns: repeat(2, 1fr); }
  .lx-steps { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 900px) {
  .lx-hero__grid, .lx-split { grid-template-columns: 1fr; }
  .lx-hero__art, .lx-split__art { order: -1; }
  .latch-art--hero { max-width: 340px; }
  .lx-faq__row { grid-template-columns: 1fr; gap: .45rem; }
}
@media (max-width: 600px) {
  .lx-grid, .lx-caps, .lx-steps { grid-template-columns: 1fr; }
  .lx-cap + .lx-cap { padding-left: 0; }
  .lx-btn { width: 100%; justify-content: center; }
}
@media (prefers-reduced-motion: reduce) { .lx-card, .lx-card::after, .lx-btn { transition: none; } }

/* ===========================================================================
   INTERIOR PAGES
   Body copy on /shipping/ measured 152 CHARACTERS per line against a
   comfortable 60-70. The column belongs to the CONTAINER, not to each child:
   constraining children alone made WordPress centre them, indenting body copy
   away from its own headings.
   !important is required, not lazy: WordPress declares margin-left:auto as
   !important in .is-layout-constrained. Verified in the browser first.
   =========================================================================== */
body:not(.home) .entry-content,
body:not(.home) .entry-header {
  max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter);
}
body:not(.home) .entry-content > *:not(.lx):not(.wp-block-columns) {
  max-width: 68ch; margin-left: 0 !important; margin-right: auto !important;
}
body:not(.home) .entry-header .page-title { font-size: var(--fs-h1); font-weight: 800; letter-spacing: -.022em; line-height: 1.08; margin: 0; }
body:not(.home) .hero-section { border-bottom: 1px solid var(--latch-line); padding-bottom: clamp(.9rem,.7rem + .6vw,1.25rem); margin-bottom: clamp(1.5rem,1.2rem + 1.2vw,2.25rem); }
body:not(.home) .entry-content h2 {
  font-size: var(--fs-h2); font-weight: 800;
  margin-top: clamp(2.25rem,1.8rem + 2vw,3.25rem); margin-bottom: .65rem;
  padding-top: 1.3rem; border-top: 1px solid var(--latch-line);
}
body:not(.home) .entry-content h2:first-of-type { margin-top: .4rem; }
body:not(.home) .entry-content h3 { font-size: var(--fs-h3); font-weight: 700; margin-top: 1.8rem; margin-bottom: .4rem; }
body:not(.home) .entry-content p  { margin-block: 0 1.05rem; }
body:not(.home) .entry-content ul { list-style: none; padding-left: 0; }
body:not(.home) .entry-content ul > li { position: relative; padding-left: 1.35rem; margin-bottom: .5rem; }
body:not(.home) .entry-content ul > li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: .5rem; height: 2px; background: var(--latch-bronze);
}
body:not(.home) .entry-content strong { font-weight: 700; color: inherit; }

/* ===========================================================================
   PHOTOGRAPHY
   Four architectural photographs, Pexels licence (commercial use, no
   attribution required), treated to a single duotone ramp so they read as one
   deliberate set rather than as stock. The treatment is not decoration: it
   kills a yellow cast on one and an orange cast on another that would both
   have fought the palette. All four at 1000w total 71 KB in WebP.
   =========================================================================== */
.lx-figure { position: relative; overflow: hidden; background: var(--latch-surface); }
.lx-figure img { display: block; width: 100%; height: 100%; object-fit: cover; }
.lx-figure--wide  { aspect-ratio: 16 / 9; }
.lx-figure--photo { aspect-ratio: 4 / 3; }

/* PHOTO HERO. The image sits UNDER a scrim, not behind raw text: at 1600w the
   photo's own highlights reach near white, and white type on it would fail
   contrast in the bright corners. The scrim is what makes the ratio provable. */
.lx-hero--photo { position: relative; isolation: isolate; }
.lx-hero--photo .lx-hero__bg {
  position: absolute; inset: 0; z-index: -2;
}
.lx-hero--photo .lx-hero__bg img { width: 100%; height: 100%; object-fit: cover; }
.lx-hero--photo::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, rgba(16,20,24,.97) 0%, rgba(16,20,24,.92) 46%, rgba(16,20,24,.62) 100%);
}
@media (max-width: 900px) {
  .lx-hero--photo::after { background: linear-gradient(180deg, rgba(16,20,24,.93) 0%, rgba(16,20,24,.97) 60%); }
}

/* ---------------------------------------------------------- PAGE HEADER */
.lx-pagehead { background: var(--latch-panel); color: var(--latch-panel-text); position: relative; isolation: isolate; }
.lx-pagehead .lx-wrap { padding-block: clamp(2.25rem, 1.7rem + 2.4vw, 3.5rem); }
.lx-pagehead h1 { font-size: clamp(1.9rem, 1.4rem + 2.2vw, 3rem); font-weight: 800; color: #fff; margin: 0; max-width: 20ch; }
.lx-pagehead__sub { color: var(--latch-panel-muted); font-size: var(--fs-lead); max-width: 56ch; margin: .8rem 0 0; }
.lx-pagehead__bg { position: absolute; inset: 0; z-index: -2; }
.lx-pagehead__bg img { width: 100%; height: 100%; object-fit: cover; }
.lx-pagehead--photo::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, rgba(16,20,24,.97) 0%, rgba(16,20,24,.90) 50%, rgba(16,20,24,.66) 100%);
}

/* ------------------------------------------------------------- CALLOUT */
.lx-callout {
  border: 1px solid var(--latch-line); border-left: 3px solid var(--latch-bronze);
  background: var(--latch-surface); padding: 1.15rem 1.35rem; margin: 0 0 1.6rem;
  max-width: 68ch;
}
.lx-callout__t { display: block; font-weight: 700; font-size: var(--fs-small); margin-bottom: .3rem; }
.lx-callout p { margin: 0; font-size: var(--fs-small); color: var(--latch-steel); }

/* ===========================================================================
   MOTION
   Progressive enhancement, deliberately: the resting state is VISIBLE, and the
   hidden start state only exists once JS adds .js-reveal to <html>. If the
   script never runs, every section is simply there. A page parked at opacity:0
   waiting on an observer is a blank page to anyone whose JS failed, and a blank
   thumbnail to every crawler and preview.
   One effect only: 14px rise and a fade. No parallax, no counters, no carousel.
   =========================================================================== */
.js-reveal .lx-rv { opacity: 0; transform: translateY(14px); }
.js-reveal .lx-rv.is-in {
  opacity: 1; transform: none;
  transition: opacity .5s cubic-bezier(.22,.61,.36,1), transform .5s cubic-bezier(.22,.61,.36,1);
}
.js-reveal .lx-rv:nth-child(2).is-in { transition-delay: .06s; }
.js-reveal .lx-rv:nth-child(3).is-in { transition-delay: .12s; }
.js-reveal .lx-rv:nth-child(4).is-in { transition-delay: .18s; }

@media (prefers-reduced-motion: reduce) {
  .js-reveal .lx-rv { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* Print and forced-colors must never inherit a hidden animation state. */
@media print { .lx-rv { opacity: 1 !important; transform: none !important; } }

/* ===========================================================================
   INTERIOR PAGE HEADER: ESCAPING THE CONSTRAINED COLUMN
   .entry-content is 1200px wide and centred on interior pages, so a bleed
   computed as calc(50% - 50vw) resolves against 1200px, not the viewport, and
   lands 120px short on each side. The header also has to cancel the container's
   own padding-inline or it stays inset by the gutter.
   Measured before writing: pagehead sat at x=152 in a 1440 viewport.
   =========================================================================== */
body:not(.home) .entry-content > .lx-pagehead {
  max-width: none !important;
  width: auto !important;
  margin-left: calc(50% - 50vw) !important;
  margin-right: calc(50% - 50vw) !important;
}

/* The interior prose rule sets `p { margin-block: 0 1.05rem }` at a higher
   specificity than the component, which collapsed the gap under the h1 to
   nothing. Restated here so the header owns its own spacing. */
body:not(.home) .entry-content .lx-pagehead__sub {
  margin: .85rem 0 0 !important;
  max-width: 56ch;
}
body:not(.home) .entry-content .lx-pagehead h1 { margin-bottom: 0; }

/* First paragraph after the header is the page's opening answer, so it gets
   a little more room and a slightly larger size than the body that follows. */
body:not(.home) .entry-content > .lx-pagehead + p {
  font-size: var(--fs-lead);
  color: var(--latch-steel);
  margin-top: clamp(1.5rem, 1.2rem + 1vw, 2.25rem);
}
