/* ===========================================================================
   Type. Self-hosted: the CSP is `font-src 'self'` and the site makes no
   third-party request of any kind. Three variable files, 157 KB, latin only.

   Instrument Serif  display  - editorial, high contrast, modern old-style
   Inter Tight       body     - neutral and legible at small sizes
   JetBrains Mono    labels   - the drawing-sheet apparatus
   =========================================================================== */
@font-face{font-family:'Instrument Serif';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/InstrumentSerif.woff2) format('woff2');}
@font-face{font-family:'Instrument Serif';font-style:italic;font-weight:400;font-display:swap;src:url(/assets/fonts/InstrumentSerif-Italic.woff2) format('woff2');}
@font-face{font-family:'Inter Tight';font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/fonts/InterTight.woff2) format('woff2');}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:100 800;font-display:swap;src:url(/assets/fonts/JetBrainsMono.woff2) format('woff2');}

/* gtalofts.com — ported from the approved mockup. Do not hand-edit _base.css
   or _additions.css expecting them to be served; style.css is the artefact. */

/* ===== Tokens ===== */
:root{
  --paper:#F6F5F1;
  --paper-raised:#FFFFFF;
  --ink:#161614;
  --ink-soft:#55544D;
  --ink-faint:#6E6C63;
  --line:#E3E1DA;
  --line-strong:#C6C3B9;
  --accent-brass:#9A7B4A;
  --accent-brass-soft:#EFE7D8;
  --accent-redline:#9C4A34;
  --accent-redline-soft:#F3E2DB;
  --accent-slate:#5A6B72;
  --accent-slate-soft:#E3E9EA;
  --accent-racing:#2F4A3C;
  --accent-racing-soft:#E1E8E3;
  --accent-cta:#161614;
  --accent-cta-hover:#3A3A35;
  /* Text drawn ON the CTA fill. A token because a light CTA (gold,
     cream) needs dark text while a dark one needs light text, and the
     nav's own `a` rule out-specifies a bare .btn-primary. */
  --cta-ink:#FFFFFF;
  --shadow:rgba(20,20,18,0.13);
  --focus:#9A7B4A;

  --font-display: 'Instrument Serif', Georgia, 'Times New Roman', serif;
  --font-body: 'Inter Tight', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', Consolas, 'SFMono-Regular', Menlo, monospace;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --paper:#141412;
    --paper-raised:#1C1C19;
    --ink:#F2F1EC;
    --ink-soft:#ADABA3;
    --ink-faint:#95938A;
    --line:#2C2C28;
    --line-strong:#413F3A;
    --accent-brass:#C9A468;
    --accent-brass-soft:#332B1C;
    --accent-redline:#CE8069;
    --accent-redline-soft:#33211C;
    --accent-slate:#94ABB3;
    --accent-slate-soft:#1E262A;
    --accent-racing:#84B79A;
    --accent-racing-soft:#1B2922;
    --accent-cta:#F2F1EC;
    --accent-cta-hover:#FFFFFF;
    --cta-ink:#141412;
    --shadow:rgba(0,0,0,0.52);
    --focus:#C9A468;
  }
}
:root[data-theme="dark"]{
  --paper:#141412;
  --paper-raised:#1C1C19;
  --ink:#F2F1EC;
  --ink-soft:#ADABA3;
  --ink-faint:#95938A;
  --line:#2C2C28;
  --line-strong:#413F3A;
  --accent-brass:#C9A468;
  --accent-brass-soft:#332B1C;
  --accent-redline:#CE8069;
  --accent-redline-soft:#33211C;
  --accent-slate:#94ABB3;
  --accent-slate-soft:#1E262A;
  --accent-racing:#84B79A;
  --accent-racing-soft:#1B2922;
  --accent-cta:#F2F1EC;
  --accent-cta-hover:#FFFFFF;
  --cta-ink:#141412;
  --shadow:rgba(0,0,0,0.52);
  --focus:#C9A468;
}
*{box-sizing:border-box;}
@media (prefers-reduced-motion: reduce){
  *{animation-duration:.001ms !important; transition-duration:.001ms !important;}
}
html{overflow-x:hidden;}
body{
  margin:0;
  overflow-x:hidden;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--font-body);
  font-size:16px;
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4{
  font-family:var(--font-display);
  font-weight:400;
  margin:0;
  text-wrap:balance;
  letter-spacing:-0.012em;
  line-height:1.12;
}
/* Instrument Serif ships a single regular weight and is drawn for display use,
   so headings are set at 400 rather than faux-bolded, and tracking is eased
   back in as size grows. */
h1{letter-spacing:-0.018em; line-height:1.02;}
.cover h1 em{font-style:italic;}
a{color:var(--accent-racing);}
:focus-visible{outline:2px solid var(--focus); outline-offset:2px;}
::selection{background:var(--accent-brass-soft); color:var(--ink);}
.wrap{max-width:1180px; margin:0 auto; padding:0 28px;}
.mono{font-family:var(--font-mono);}
.label{
  font-family:var(--font-mono);
  font-size:.72rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--ink-faint);
}
/* ===== Drawing-sheet chrome ===== */
.sheet{position:relative; padding:64px 0;}
.sheet::before, .sheet::after{
  content:"";
  position:absolute;
  width:16px; height:16px;
  background:
    linear-gradient(var(--line-strong), var(--line-strong)) center/100% 1.4px no-repeat,
    linear-gradient(var(--line-strong), var(--line-strong)) center/1.4px 100% no-repeat;
  opacity:.55;
}
/* The corner ticks sit just outside the 1180px wrap. Below ~1196px viewport
   that offset goes negative, and a negative `right` pushed the page ~395px
   wider than the screen on every phone. Clamp it to the gutter instead. */
.sheet::before{top:20px; left:max(8px, calc(50% - 590px + 8px));}
.sheet::after{bottom:20px; right:max(8px, calc(50% - 590px + 8px));}
.sheet + .sheet{border-top:1px solid var(--line);}
.sheet-head{
  display:flex; align-items:baseline; gap:16px; flex-wrap:wrap;
  margin-bottom:28px;
}
.sheet-tag{
  font-family:var(--font-mono); font-size:.8rem; letter-spacing:.1em;
  color:var(--accent-racing); border:1px solid var(--accent-racing);
  padding:3px 9px; border-radius:2px; white-space:nowrap;
}
.sheet-head h2{font-size:1.5rem;}
.sheet-sub{color:var(--ink-soft); max-width:62ch; margin-top:6px;}
/* ===== Header ===== */
header{
  position:sticky; top:0; z-index:40;
  background:var(--paper); border-bottom:1px solid var(--line);
}
header .bar{
  display:flex; align-items:center; justify-content:space-between;
  /* This element is also a .wrap. `padding:16px 0` (as the mockup had it) beats
     .wrap's `0 28px` on specificity and wiped out the side gutter, so the header
     sat flush against the screen edge on every viewport under 1180px. Keep the
     horizontal gutter here. */
  padding:16px 28px;
}
.wordmark{
  font-family:var(--font-display); font-weight:700; font-size:1.25rem;
  letter-spacing:.04em;
}
.wordmark span{color:var(--accent-racing);}
nav.primary{display:flex; align-items:center; gap:26px;}
nav.primary a{
  font-size:.86rem; letter-spacing:.03em; color:var(--ink); text-decoration:none;
  border-bottom:1px solid transparent; padding-bottom:2px;
}
nav.primary a:hover{border-color:var(--accent-brass);}
@media (max-width: 860px){ nav.primary a.hide-sm{display:none;} }
.btn{
  font-family:var(--font-mono); font-size:.78rem; letter-spacing:.05em; text-transform:uppercase;
  border:1px solid var(--ink); background:transparent; color:var(--ink);
  padding:10px 16px; border-radius:2px; cursor:pointer; text-decoration:none; display:inline-flex; align-items:center; gap:8px;
  transition:background .15s, color .15s, border-color .15s;
}
.btn:hover{background:var(--ink); color:var(--paper);}
.btn-primary,
nav.primary a.btn-primary{
  background:var(--accent-cta); border-color:var(--accent-cta); color:var(--cta-ink);
}
.btn-primary:hover,
nav.primary a.btn-primary:hover{
  background:var(--accent-cta-hover); border-color:var(--accent-cta-hover); color:var(--cta-ink);
}
.btn-ghost{border-color:var(--line-strong); color:var(--ink-soft);}
.btn-ghost:hover{background:var(--paper-raised); color:var(--ink);}
.btn-sm{padding:7px 12px; font-size:.7rem;}
/* ===== Cover / hero ===== */
.cover{padding:56px 0 40px; overflow:hidden; position:relative;}
.cover-gradient{
  position:absolute; inset:-15% -15%; z-index:0; pointer-events:none;
  background:
    radial-gradient(circle at 15% 20%, color-mix(in srgb, var(--accent-brass) 24%, transparent) 0%, transparent 55%),
    radial-gradient(circle at 85% 10%, color-mix(in srgb, var(--accent-racing) 26%, transparent) 0%, transparent 50%),
    radial-gradient(circle at 55% 95%, color-mix(in srgb, var(--accent-slate) 18%, transparent) 0%, transparent 55%);
  background-repeat:no-repeat;
  background-size: 140% 140%;
  background-position: 0% 0%, 100% 0%, 50% 100%;
  animation: gradientDrift 17s ease-in-out infinite alternate;
}
@keyframes gradientDrift{
  to{ background-position: 22% 18%, 78% 22%, 42% 84%; }
}
.cover .wrap{position:relative; z-index:1;}
.cover-grid{
  display:grid; grid-template-columns: 1.5fr 1fr; gap:48px; align-items:start; position:relative;
}
@media (max-width: 900px){ .cover-grid{grid-template-columns:1fr;} }
.eyebrow{
  font-family:var(--font-mono); font-size:.76rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--accent-slate); margin-bottom:14px; display:block;
}
.cover h1{
  font-size:clamp(2.1rem, 4.6vw, 3.6rem);
  line-height:1.03;
  max-width:14ch;
}
.cover h1 em{font-style:normal; color:var(--accent-racing);}
.cover p.lede{
  margin-top:20px; max-width:52ch; color:var(--ink-soft); font-size:1.05rem;
}
.cover-ctas{display:flex; gap:14px; margin-top:28px; flex-wrap:wrap;}
.titleblock{
  border:1px solid var(--line-strong); background:var(--paper-raised);
  font-family:var(--font-mono); font-size:.82rem;
}
.titleblock .tb-head{
  padding:10px 16px; border-bottom:1px solid var(--line-strong);
  letter-spacing:.08em; text-transform:uppercase; font-size:.72rem; color:var(--ink-faint);
}
.titleblock dl{display:grid; grid-template-columns:auto 1fr; gap:2px 14px; margin:0; padding:14px 16px;}
.titleblock dt{color:var(--ink-faint);}
.titleblock dd{margin:0; color:var(--ink);}
.titleblock .row{grid-column:1 / -1; border-top:1px dashed var(--line); margin-top:6px; padding-top:6px;}
/* ===== Stamp strip ===== */
.stamps{
  display:flex; gap:26px; flex-wrap:wrap; padding:26px 0 10px;
  border-top:1px solid var(--line); border-bottom:1px solid var(--line);
}
.stamp{
  width:104px; height:104px; border-radius:50%; border:1.5px dashed var(--accent-brass);
  display:flex; align-items:center; justify-content:center; text-align:center;
  transform:rotate(-6deg); flex-shrink:0; overflow:hidden;
}
.stamp:nth-child(2){transform:rotate(4deg); border-color:var(--accent-slate);}
.stamp:nth-child(3){transform:rotate(-3deg); border-color:var(--accent-racing);}
.stamp:nth-child(4){transform:rotate(5deg); border-color:var(--accent-brass);}
.stamp b{
  display:block; font-family:var(--font-mono); font-size:.58rem; letter-spacing:.03em;
  text-transform:uppercase; line-height:1.25; padding:0 6px;
}
/* ===== Filter bar ===== */
.filterbar{
  display:flex; gap:14px; align-items:center; flex-wrap:wrap; padding:20px 0;
}
.filterbar .group{display:flex; gap:8px; align-items:center; flex-wrap:wrap;}
.pill{
  font-family:var(--font-mono); font-size:.76rem; letter-spacing:.03em;
  border:1px solid var(--line-strong); background:transparent; color:var(--ink-soft);
  padding:7px 14px; border-radius:999px; cursor:pointer; display:inline-flex; align-items:center; gap:7px;
}
.pill .dot{width:8px; height:8px; border-radius:50%; background:currentColor;}
.pill[aria-pressed="true"]{background:var(--ink); border-color:var(--ink); color:var(--paper);}
.pill.hard[aria-pressed="true"]{background:var(--accent-brass); border-color:var(--accent-brass); color:#241a06;}
.pill.soft[aria-pressed="true"]{background:var(--accent-slate); border-color:var(--accent-slate); color:#04191f;}
.pill.hybrid[aria-pressed="true"]{background:var(--accent-racing); border-color:var(--accent-racing); color:#fff;}
input.search{
  font-family:var(--font-body); font-size:.9rem; padding:9px 14px; border:1px solid var(--line-strong);
  border-radius:2px; background:var(--paper-raised); color:var(--ink); min-width:220px;
}
select.neigh{
  font-family:var(--font-body); font-size:.9rem; padding:9px 14px; border:1px solid var(--line-strong);
  border-radius:2px; background:var(--paper-raised); color:var(--ink);
}
.count-note{font-family:var(--font-mono); font-size:.78rem; color:var(--ink-faint); margin-left:auto;}
/* ===== Map ===== */
.maplayout{display:grid; grid-template-columns: 1fr 300px; gap:26px; align-items:start;}
@media (max-width:900px){ .maplayout{grid-template-columns:1fr;} }
.mapcard{
  border:1px solid var(--line-strong); background:var(--paper-raised);
  padding:14px; position:relative;
}
.mapinner{position:relative;}
#mapsvg{width:100%; height:auto; display:block;}
.rd-secondary{fill:none; stroke:var(--line); stroke-width:1; stroke-linejoin:round; stroke-linecap:round;}
.rd-primary{fill:none; stroke:var(--line-strong); stroke-width:1.6; stroke-linejoin:round; stroke-linecap:round;}
.rd-motorway{fill:none; stroke:var(--accent-redline); stroke-width:2.2; stroke-linejoin:round; stroke-linecap:round; opacity:.55;}
.lake{fill:var(--accent-slate); opacity:.24;}
.lake-label{fill:var(--accent-slate); font-family:var(--font-mono); font-size:12px; letter-spacing:.14em;}
.hood-label{fill:var(--ink-faint); font-family:var(--font-mono); font-size:9.5px; letter-spacing:.08em; opacity:.85;}
.pin circle{
  stroke:var(--paper-raised); stroke-width:1.6; cursor:pointer;
  transform-box:fill-box; transform-origin:center;
}
.pin{cursor:pointer;}
.pin:hover circle, .pin:focus circle{filter:drop-shadow(0 0 5px var(--shadow));}
.pin.dim{opacity:.14;}
.pin.hard circle{fill:var(--accent-brass);}
.pin.soft circle{fill:var(--accent-slate);}
.pin.hybrid circle{fill:var(--accent-racing);}
.pin.active circle{stroke:var(--ink); stroke-width:2.4;}
.hovercard{
  position:fixed; z-index:80; width:200px; pointer-events:none;
  background:var(--paper-raised); border:1px solid var(--line-strong); box-shadow:0 10px 26px var(--shadow);
  opacity:0; visibility:hidden; transform:translateY(4px);
  transition:opacity .12s ease, transform .12s ease;
}
.hovercard.show{opacity:1; visibility:visible; transform:translateY(0);}
.hovercard .hc-img{width:100%; height:110px; display:block; background:var(--paper);}
.hovercard .hc-body{padding:9px 11px;}
.hovercard .hc-name{font-family:var(--font-display); font-size:.92rem; line-height:1.15;}
.hovercard .hc-meta{font-family:var(--font-mono); font-size:.66rem; letter-spacing:.04em; color:var(--ink-soft); margin-top:4px;}
.mapzoom{
  position:absolute; right:12px; bottom:12px; z-index:10;
  display:flex; flex-direction:column; border:1px solid var(--line-strong); background:var(--paper-raised);
}
.mapzoom button{
  width:32px; height:32px; border:none; background:none; color:var(--ink);
  font-family:var(--font-mono); font-size:1rem; cursor:pointer; line-height:1;
}
.mapzoom button + button{border-top:1px solid var(--line-strong);}
.mapzoom button:hover{background:var(--accent-racing-soft); color:var(--accent-racing);}
.maphint{
  position:absolute; left:12px; bottom:12px; z-index:10;
  font-family:var(--font-mono); font-size:.68rem; letter-spacing:.03em; color:var(--ink-faint);
  background:var(--paper-raised); border:1px solid var(--line-strong); padding:4px 9px;
  pointer-events:none;
}
@media (max-width:640px){ .maphint{display:none;} }
#mapsvg{touch-action:none; cursor:grab;}
#mapsvg:active{cursor:grabbing;}
.legend{display:flex; flex-direction:column; gap:10px;}
.legend .lg-title{font-family:var(--font-mono); font-size:.72rem; letter-spacing:.1em; color:var(--ink-faint); text-transform:uppercase; margin-bottom:2px;}
.legend .lg-item{display:flex; align-items:center; gap:9px; font-size:.86rem;}
.legend .sw{width:11px; height:11px; border-radius:50%; flex-shrink:0;}
.legend .sw.hard{background:var(--accent-brass);}
.legend .sw.soft{background:var(--accent-slate);}
.legend .sw.hybrid{background:var(--accent-racing);}
.legend .lg-note{font-size:.8rem; color:var(--ink-soft); margin-top:8px; padding-top:10px; border-top:1px dashed var(--line);}
.legend .lg-attrib{font-size:.7rem; color:var(--ink-faint); margin-top:10px;}
/* ===== Index grid ===== */
.index-grid{
  display:grid; grid-template-columns:repeat(auto-fill, minmax(240px,1fr)); gap:16px; margin-top:8px;
}
.card{
  border:1px solid var(--line-strong); background:var(--paper-raised);
  padding:0; cursor:pointer; text-align:left; font:inherit; color:inherit;
  display:flex; flex-direction:column; overflow:hidden;
}
.card.hidden{display:none;}
.card .elev-thumb{width:100%; height:120px; background:var(--paper); display:block; border-bottom:1px solid var(--line);}
.card-body{padding:14px; display:flex; flex-direction:column; gap:8px;}
.card-top{display:flex; justify-content:space-between; align-items:flex-start; gap:8px;}
.card h3{font-size:1.0rem; line-height:1.2;}
.badge{
  font-family:var(--font-mono); font-size:.62rem; letter-spacing:.08em; text-transform:uppercase;
  padding:3px 7px; border-radius:2px; white-space:nowrap; flex-shrink:0;
}
/* Text is the theme ink, not the accent. At 9.92px the accent-on-tint pairing
   sat at 2.8-4.5:1 in every palette, which fails AA for small text. The tint
   and the border still carry the type's colour. */
.badge.hard{background:var(--accent-brass-soft); color:var(--ink); box-shadow:inset 0 0 0 1px var(--accent-brass);}
.badge.soft{background:var(--accent-slate-soft); color:var(--ink); box-shadow:inset 0 0 0 1px var(--accent-slate);}
.badge.hybrid{background:var(--accent-racing-soft); color:var(--ink); box-shadow:inset 0 0 0 1px var(--accent-racing);}
.card .addr{font-family:var(--font-mono); font-size:.76rem; color:var(--ink-soft);}
.card .use{font-size:.84rem; color:var(--ink-soft);}
.card .facts{
  display:flex; gap:12px; font-family:var(--font-mono); font-size:.72rem; color:var(--ink-faint);
  border-top:1px dashed var(--line); padding-top:8px; margin-top:2px; flex-wrap:wrap;
}
.card .facts b{color:var(--ink);}
/* ===== Profile sheet ===== */
#profile.sheet{display:none;}
#profile.sheet.open{display:block;}
.profile-head{display:flex; justify-content:space-between; gap:20px; flex-wrap:wrap; align-items:flex-start;}
.profile-head h2{font-size:1.9rem;}
.profile-hero{width:100%; max-width:420px; height:220px; border:1px solid var(--line-strong); background:var(--paper-raised); margin-top:20px;}
.profile-grid{display:grid; grid-template-columns:1fr 1fr; gap:36px; margin-top:30px;}
@media (max-width:820px){ .profile-grid{grid-template-columns:1fr;} }
.factsheet{border:1px solid var(--line); }
.factsheet .fr{display:flex; justify-content:space-between; gap:10px; padding:11px 16px; font-size:.9rem;}
.factsheet .fr + .fr{border-top:1px solid var(--line);}
.factsheet .fr dt{color:var(--ink-faint); font-family:var(--font-mono); font-size:.76rem; letter-spacing:.04em; text-transform:uppercase;}
.factsheet .fr dd{margin:0; text-align:right; font-weight:600;}
/* ===== Forms ===== */
form .frow{display:flex; gap:10px; flex-wrap:wrap;}
form input[type=text], form input[type=email], form input[type=tel],
form input[type=password], form input[type=search], form input[type=number],
form input[type=url], form textarea, form select{
  font-family:var(--font-body); font-size:.92rem; padding:10px 12px; border:1px solid var(--line-strong);
  background:var(--paper); color:var(--ink); border-radius:2px; flex:1; min-width:160px;
}
form textarea{width:100%; min-height:80px; resize:vertical;}
.confirm{
  display:none; margin-top:10px; padding:10px 12px; border:1px solid var(--accent-slate);
  background:var(--accent-slate-soft); color:var(--ink); font-size:.85rem;
}
.confirm.show{display:block;}
/* ===== Valuation sheet ===== */
.valuation-grid{display:grid; grid-template-columns:1fr 1.1fr; gap:44px;}
@media (max-width:860px){ .valuation-grid{grid-template-columns:1fr;} }
.permit-card{border:1px solid var(--line-strong); background:var(--paper-raised); padding:24px;}
.permit-card .pc-head{
  display:flex; justify-content:space-between; border-bottom:1px solid var(--line-strong); padding-bottom:12px; margin-bottom:18px;
}
.permit-card .pc-head .num{font-family:var(--font-mono); color:var(--ink-faint); font-size:.78rem;}
/* ===== Testimonials page ===== */
.testimonial-grid{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(280px,1fr)); gap:20px; margin-top:12px;
}
.testimonial-card{
  border:1px dashed var(--line-strong); background:var(--paper-raised); padding:26px 22px;
  display:flex; flex-direction:column; gap:12px;
}
.tq-mark{font-family:var(--font-display); font-size:2.6rem; line-height:0.6; color:var(--accent-racing); opacity:.5;}
.tq-text{color:var(--ink-soft); font-style:italic; font-size:.95rem; line-height:1.6;}
.tq-attrib{font-family:var(--font-mono); font-size:.72rem; letter-spacing:.04em; color:var(--ink-faint); text-transform:uppercase; border-top:1px dashed var(--line); padding-top:10px;}
.testimonial-cta{
  margin-top:34px; padding-top:24px; border-top:1px solid var(--line);
  display:flex; justify-content:space-between; align-items:center; gap:20px; flex-wrap:wrap;
}
.testimonial-cta p{color:var(--ink-soft); max-width:52ch; margin:0;}
/* ===== Footer ===== */
footer{border-top:1px solid var(--line); padding:40px 0 30px; margin-top:20px;}
.footgrid{display:flex; justify-content:space-between; gap:30px; flex-wrap:wrap; font-size:.85rem; color:var(--ink-soft);}
.footgrid .fcol h5{font-family:var(--font-mono); font-size:.72rem; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-faint); margin-bottom:10px;}
.footgrid a{color:var(--ink-soft); text-decoration:none;}
.footgrid a:hover{color:var(--ink);}
.footnote{margin-top:26px; padding-top:18px; border-top:1px dashed var(--line); font-size:.76rem; color:var(--ink-faint); font-family:var(--font-mono);}

/* ===========================================================================
   Additions for the server-rendered site.

   Everything above this point is the mockup's stylesheet, unchanged apart from
   removing the rules that styled the SPA preloader, the modal, and the
   fabricated listing cards and price chart.
   =========================================================================== */

/* ===== Utility ===== */
.wrap.narrow{max-width:760px;}
.mt0{margin-top:0;}
.sr{
  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:200;
  /* The theme's two poles, so it cannot invert into low contrast whatever the
     accent happens to be in a given palette. */
  background:var(--ink); color:var(--paper); padding:12px 18px;
  font-family:var(--font-mono); font-size:.8rem;
}
.skip:focus{left:0;}
p.lede{margin-top:18px; max-width:64ch; color:var(--ink-soft); font-size:1.05rem;}
.fsub{color:var(--ink-faint); font-size:.86rem; max-width:64ch;}
.biglist{max-width:64ch; color:var(--ink-soft); padding-left:22px;}
.biglist li{margin-bottom:8px;}
.btn-lg{padding:13px 22px; font-size:.82rem;}
.linkbtn{
  background:none; border:none; padding:0; font:inherit; color:var(--accent-racing);
  text-decoration:underline; cursor:pointer;
}

/* ===== Staging banner ===== */
.stagingbar{
  background:var(--accent-redline); color:#fff; padding:9px 20px;
  font-family:var(--font-mono); font-size:.74rem; letter-spacing:.03em; text-align:center;
}
.stagingbar strong{letter-spacing:.1em; text-transform:uppercase;}

/* ===== Header additions ===== */
.wordmark{display:inline-flex; align-items:center; gap:9px; color:var(--ink); text-decoration:none;}
.wordmark .mark{display:block; color:var(--accent-racing);}
nav.primary a[aria-current="page"]{border-color:var(--accent-racing);}
@media (max-width:720px){
  header .bar{flex-wrap:wrap; gap:10px;}
  nav.primary{gap:16px; flex-wrap:wrap;}
  nav.primary a{font-size:.8rem;}
}

/* ===== Breadcrumbs ===== */
.crumbs{
  font-family:var(--font-mono); font-size:.72rem; letter-spacing:.04em;
  color:var(--ink-faint); margin:0 0 18px;
}
.crumbs a{color:var(--ink-soft); text-decoration:none;}
.crumbs a:hover{color:var(--ink); text-decoration:underline;}
.crumbs .sep{margin:0 7px; opacity:.6;}
.crumbs [aria-current="page"]{color:var(--ink);}

/* ===== Disclosures =====
   These carry regulatory weight, so they are styled to be read rather than
   tucked away at 9px in a corner. */
.disc{
  font-family:var(--font-mono); font-size:.72rem; line-height:1.5; letter-spacing:.02em;
  color:var(--ink-soft); margin:8px 0 0;
}
.disc-warn{
  color:var(--accent-redline); border-left:2px solid var(--accent-redline);
  padding-left:10px;
}
.discbox{
  margin-top:26px; padding:14px 18px; border:1px dashed var(--line-strong);
  background:var(--paper-raised);
}
.discbox p{
  font-family:var(--font-mono); font-size:.73rem; line-height:1.55;
  color:var(--ink-soft); margin:0;
}
.discbox p + p{margin-top:8px;}
.unver{
  display:inline-block; font-family:var(--font-mono); font-size:.6rem; letter-spacing:.08em;
  text-transform:uppercase; color:var(--accent-redline); border:1px solid var(--accent-redline);
  padding:1px 5px; border-radius:2px; margin-left:5px; vertical-align:1px;
}

/* ===== Building figure ===== */
.bfig{margin:0;}
.bfig img{
  display:block; width:100%; height:auto;
  border:1px solid var(--line-strong); background:var(--paper-raised);
}
.bfig-marker{
  border:1px solid var(--line-strong); background:var(--paper-raised);
  aspect-ratio:240 / 200;
}
.bfig-hero .bfig-marker{max-width:460px;}
.vfig{margin:0;}
.vfig video{
  display:block; width:100%; height:auto; border:1px solid var(--line-strong);
  background:var(--paper-raised);
}
.herovid{padding:10px 0 30px;}

/* ===== Cards as links ===== */
a.card{text-decoration:none; color:inherit; transition:transform .18s ease, box-shadow .18s ease;}
a.card:hover{transform:translateY(-3px); box-shadow:0 12px 26px var(--shadow);}
a.card:focus-visible{outline:2px solid var(--focus); outline-offset:2px;}
.card h3{color:var(--ink);}
.index-grid.dense{grid-template-columns:repeat(auto-fill, minmax(268px,1fr));}
.badge.big{font-size:.72rem; padding:5px 11px;}
.badge.count{background:var(--accent-racing-soft); color:var(--accent-racing);}
.ncard .card-body{gap:10px;}
.noresults{
  padding:26px; border:1px dashed var(--line-strong); text-align:center;
  color:var(--ink-soft); margin-top:16px;
}
.activefilter{
  font-family:var(--font-mono); font-size:.78rem; color:var(--ink-soft);
  padding:10px 14px; background:var(--paper-raised); border:1px solid var(--line);
}

/* ===== Profile page ===== */
.paddr{font-family:var(--font-mono); font-size:.86rem; color:var(--ink-soft); margin-top:8px;}
.profile-grid{align-items:start;}

/* ===== Stat line ===== */
.statline{display:flex; gap:34px; flex-wrap:wrap; margin-top:24px; padding-top:20px; border-top:1px solid var(--line);}
.statline .st b{
  display:block; font-family:var(--font-display); font-size:1.9rem; line-height:1.1; color:var(--ink);
}
.statline .st span{
  font-family:var(--font-mono); font-size:.7rem; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-faint);
}

/* ===== Triptych ===== */
.triptych{display:grid; grid-template-columns:repeat(auto-fit, minmax(240px,1fr)); gap:20px;}
.tri{border:1px solid var(--line); padding:20px; background:var(--paper-raised);}
.tri-head{display:flex; flex-direction:column; gap:8px; margin-bottom:12px;}
.tri-count{font-family:var(--font-mono); font-size:.7rem; color:var(--ink-faint); letter-spacing:.06em;}
.tri p{margin:0; font-size:.9rem; color:var(--ink-soft);}

/* ===== Lists ===== */
.uselist{padding-left:20px; max-width:70ch;}
.uselist li{margin-bottom:10px; color:var(--ink-soft);}
.uselist a{font-weight:600;}
.minorlist{list-style:none; padding:0; display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:6px;}
.minorlist li{
  display:flex; justify-content:space-between; gap:10px; padding:8px 12px;
  border:1px solid var(--line); background:var(--paper-raised); font-size:.88rem;
}
.minorlist a{text-decoration:none;}
.mcount{font-family:var(--font-mono); font-size:.72rem; color:var(--ink-faint);}

/* ===== Agent strip ===== */
.agentstrip{
  display:flex; justify-content:space-between; gap:24px; flex-wrap:wrap; align-items:center;
  border:1px solid var(--line-strong); background:var(--paper-raised); padding:22px 24px; margin-top:26px;
}
.agentstrip p{margin:0;}
.agname{font-family:var(--font-display); font-size:1.2rem; font-weight:700;}
.agmeta{font-size:.84rem; color:var(--ink-soft);}
.agactions{display:flex; gap:10px; flex-wrap:wrap;}

/* ===== Empty state ===== */
.emptystate{
  border:1px dashed var(--line-strong); background:var(--paper-raised); padding:32px 30px;
  max-width:70ch;
}
.emptystate p{color:var(--ink-soft);}

/* ===== FAQ ===== */
details.faq{border-bottom:1px solid var(--line); padding:4px 0;}
details.faq summary{
  cursor:pointer; padding:14px 0; font-family:var(--font-display); font-weight:700; font-size:1.02rem;
  list-style:none; display:flex; justify-content:space-between; gap:14px; align-items:baseline;
}
details.faq summary::-webkit-details-marker{display:none;}
details.faq summary::after{content:"+"; font-family:var(--font-mono); color:var(--accent-brass); flex-shrink:0;}
details.faq[open] summary::after{content:"\2212";}
details.faq .fa{padding:0 0 16px;}
details.faq .fa p{margin:0; color:var(--ink-soft); max-width:70ch;}

/* ===== CTA band ===== */
.ctaband{
  border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  background:var(--paper-raised); padding:48px 0; margin-top:30px; text-align:center;
}
.ctaband h2{font-size:1.7rem;}
.ctaband p{color:var(--ink-soft); max-width:58ch; margin:14px auto 0;}
.ctaband .cover-ctas{justify-content:center;}

/* ===== Footer additions ===== */
.footgrid .fcol ul{list-style:none; padding:0; margin:0;}
.footgrid .fcol li{margin-bottom:7px;}
.footnote p{margin:0 0 12px; line-height:1.6;}
.footnote .registrant{
  font-family:var(--font-body); font-size:.86rem; color:var(--ink-soft);
  padding-bottom:12px; margin-bottom:14px; border-bottom:1px dashed var(--line);
}
.footnote .registrant strong{color:var(--ink);}

/* ===== Forms ===== */
.formcard{
  border:1px solid var(--line-strong); background:var(--paper-raised); padding:26px;
}
.formcard.compact{padding:20px; margin-top:22px;}
.formcard.sent{border-color:var(--accent-cta); border-left-width:3px;}
.formcard h3{font-size:1.15rem;}
.formcard .fsub, .formcard .fsub *{font-size:.86rem;}
.fsub{margin-top:6px;}
.field{margin-top:14px; flex:1 1 180px; min-width:0;}
.frow{display:flex; gap:12px; flex-wrap:wrap;}
.field label{
  display:block; font-family:var(--font-mono); font-size:.72rem; letter-spacing:.06em;
  text-transform:uppercase; color:var(--ink-soft); margin-bottom:6px;
}
.field label .hint, .field label .req{
  text-transform:none; letter-spacing:0; font-size:.68rem; color:var(--ink-faint);
}
.field label .req{color:var(--accent-redline);}
.field input, .field select, .field textarea{width:100%;}
.field.consent{margin-top:18px;}
.field.consent label{
  display:flex; gap:10px; align-items:flex-start; text-transform:none; letter-spacing:0;
  font-family:var(--font-body); font-size:.84rem; color:var(--ink-soft); line-height:1.5;
}
.field.consent input{width:auto; flex-shrink:0; margin-top:2px;}
.formnote{font-size:.74rem; color:var(--ink-faint); margin-top:14px; line-height:1.5;}
.formcard button[type=submit]{margin-top:18px;}
.hp{position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden;}
.alert{padding:13px 16px; border-radius:2px; font-size:.88rem; margin-bottom:16px;}
.alert-err{background:var(--accent-redline-soft); border:1px solid var(--accent-redline); color:var(--ink);}
.alert-ok{background:var(--accent-racing-soft); border:1px solid var(--accent-racing); color:var(--ink);}
.errlist{margin:8px 0 0; padding-left:20px;}
.errlist li{margin-bottom:4px;}

/* ===== Filter bar ===== */
.filterbar[hidden]{display:none;}
.card.hidden{display:none;}

/* ===== Map: pins are real links now ===== */
a.pin{cursor:pointer;}
a.pin circle{
  stroke:var(--paper-raised); stroke-width:1.6;
  transform-box:fill-box; transform-origin:center;
}
a.pin:hover circle, a.pin:focus circle{filter:drop-shadow(0 0 5px var(--shadow));}
a.pin:focus-visible circle{stroke:var(--focus); stroke-width:2.6;}
#mapsvg{touch-action:none;}
#mapsvg.pannable{cursor:grab;}
#mapsvg.pannable:active{cursor:grabbing;}
.mapzoom[hidden]{display:none;}

/* ===========================================================================
   Admin
   =========================================================================== */
body.admin-body{background:var(--paper);}
.login-shell{max-width:400px; margin:8vh auto; padding:0 22px;}
.admin-shell{max-width:1080px; margin:0 auto; padding:26px 22px 60px;}
.admin-top{display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin-bottom:22px;}
.admin-top h1{font-size:1.3rem;}
.admin-top .spacer{flex:1;}
.stat-row{display:flex; gap:14px; flex-wrap:wrap; margin-bottom:22px;}
.stat-row .stat{
  border:1px solid var(--line-strong); background:var(--paper-raised); padding:14px 20px; min-width:130px;
}
.stat-row .stat b{display:block; font-family:var(--font-display); font-size:1.7rem; line-height:1.1;}
.stat-row .stat span{
  font-family:var(--font-mono); font-size:.68rem; letter-spacing:.07em;
  text-transform:uppercase; color:var(--ink-faint);
}
.lcard{border:1px solid var(--line-strong); background:var(--paper-raised); padding:18px 20px; margin-bottom:14px;}
.lcard.st-new{border-left:3px solid var(--accent-cta);}
.lcard.st-junk{opacity:.6;}
.lcard-head{display:flex; gap:10px; align-items:baseline; flex-wrap:wrap;}
.lcard-head h3{margin:0; font-size:1.05rem;}
.lcard-when{margin-left:auto; font-family:var(--font-mono); font-size:.7rem; color:var(--ink-faint);}
.pill.tag{
  font-family:var(--font-mono); font-size:.62rem; letter-spacing:.08em; text-transform:uppercase;
  padding:2px 8px; border:1px solid var(--line-strong); border-radius:999px; color:var(--ink-soft);
}
.lead-detail{font-size:.9rem; margin:12px 0; line-height:1.7;}
.lead-msg{
  font-size:.92rem; background:var(--paper); border:1px solid var(--line);
  padding:12px 14px; margin:12px 0; white-space:pre-wrap;
}
.lead-tech{font-family:var(--font-mono); font-size:.68rem; color:var(--ink-faint); margin:8px 0 0;}
.lead-actions{display:flex; gap:10px; align-items:flex-end; flex-wrap:wrap; margin-top:14px;}
.lead-actions .field{margin:0;}
.btn-danger{border-color:var(--accent-redline); color:var(--accent-redline);}
.btn-danger:hover{background:var(--accent-redline); color:#fff;}
.blockerlist{margin:0; padding-left:20px; font-size:.88rem;}
.blockerlist li{margin-bottom:6px;}
@media (max-width:640px){
  .admin-shell{padding:18px 14px 50px;}
  .lead-actions{flex-direction:column; align-items:stretch;}
}
/* ===== Scroll reveal (replaces GSAP/ScrollTrigger) ===== */
/* Content is visible by default and stays visible if anything at all goes
   wrong. The hidden state only exists inside html.reveal-ready, which site.js
   adds ONLY after confirming IntersectionObserver is available and the user
   has not asked for reduced motion — and which it removes again on a failsafe
   timer. A broken script, a blocked script or a stalled transition therefore
   degrades to "no animation", never to "no content". */
.will-reveal{opacity:1;}

html.reveal-ready .will-reveal{
  opacity:0;
  transform:translateY(14px);
  transition:opacity .5s ease, transform .5s ease;
}
html.reveal-ready .will-reveal.is-in{
  opacity:1;
  transform:none;
}
html.reveal-ready .index-grid .card.will-reveal{transition-delay:.04s;}

@media (prefers-reduced-motion: reduce){
  html.reveal-ready .will-reveal{opacity:1 !important; transform:none !important;}
}

/* ===== Schematic marker label =====
   The isometric block is generated from the building's name and describes
   nothing about the real structure, so every instance says so on its own face.
   A card can be seen out of context — in a share preview, or scrolled to
   without the section heading — and must still not read as a picture of the
   building. */
.elev-thumb{position:relative;}
img.elev-thumb{object-fit:cover;}
.thumbtag{
  position:absolute; left:0; bottom:0;
  font-family:var(--font-mono); font-size:.56rem; letter-spacing:.1em; text-transform:uppercase;
  color:var(--paper); background:var(--accent-redline);
  padding:2px 7px; cursor:help;
}

/* Form headings are h2 so no page skips a heading level; they should still read
   as a card title rather than a section title. */
.formcard .fhead{font-size:1.15rem;}

/* Card titles carry the heading level their page's outline needs, so size is
   set on the card rather than by tag. */
.card h2, .card h3, .card h4{font-size:1rem; line-height:1.2; margin:0;}

/* The staging banner is verbose by design — it names the outstanding blocker.
   On a phone that is several lines, so give it a smaller, tighter treatment
   rather than a wall of text. It disappears entirely once the site is live. */
@media (max-width:640px){
  .stagingbar{font-size:.64rem; line-height:1.45; padding:7px 14px; text-align:left;}
}

/* ===========================================================================
   Full-bleed video cover
   =========================================================================== */
.cover.has-video{
  padding:0;
  min-height:min(86vh, 780px);
  display:flex;
  align-items:center;
  position:relative;
  isolation:isolate;
  border-bottom:1px solid var(--line);
}
.cover-media{
  position:absolute; inset:0; z-index:-1; overflow:hidden;
}
.cover-media video{
  width:100%; height:100%; object-fit:cover; display:block;
  filter:saturate(0.9) contrast(1.06) brightness(1.12);
}
/* The footage is mid-tone and busy, so the copy needs a guaranteed floor of
   contrast rather than a hopeful overlay. Two layers: a flat tint that carries
   the site's ink colour, and a directional gradient that is heaviest where the
   headline sits. */
.cover-scrim{
  position:absolute; inset:0;
  background:
    linear-gradient(100deg,
      rgba(9,20,14,0.86) 0%,
      rgba(9,20,14,0.62) 32%,
      rgba(9,20,14,0.24) 60%,
      rgba(9,20,14,0.10) 100%),
    linear-gradient(to top, rgba(9,20,14,0.55) 0%, rgba(9,20,14,0) 45%);
}
.cover.has-video .wrap{padding-top:64px; padding-bottom:44px;}

/* Inside the cover the palette is fixed light-on-dark in both themes — it sits
   on footage, not on the page background. The accent is its own token because
   the page accent is chosen to work on paper and is usually too dark to read
   against the scrim. */
.cover.has-video{
  --cover-ink:#FBF8F0;
  --cover-accent:#D9B87C;
}
.cover.has-video .eyebrow{color:rgba(251,248,240,0.72);}
.cover.has-video h1{color:var(--cover-ink);}
.cover.has-video h1 em{color:var(--cover-accent); font-style:italic;}
.cover.has-video p.lede{color:rgba(251,248,240,0.86);}
.cover.has-video .btn-ghost{border-color:rgba(251,248,240,0.5); color:#FBF8F0;}
.cover.has-video .btn-ghost:hover{background:rgba(251,248,240,0.12); color:#fff;}

.cover.has-video .titleblock{
  background:rgba(10,24,17,0.62);
  border-color:rgba(251,248,240,0.28);
  backdrop-filter:blur(9px);
  -webkit-backdrop-filter:blur(9px);
}
.cover.has-video .titleblock .tb-head{
  color:rgba(251,248,240,0.62); border-bottom-color:rgba(251,248,240,0.28);
}
.cover.has-video .titleblock dt{color:rgba(251,248,240,0.6);}
.cover.has-video .titleblock dd{color:#FBF8F0;}
.cover.has-video .titleblock dd a{color:#7FD1A3;}
.cover.has-video .titleblock .row{border-top-color:rgba(251,248,240,0.24);}

/* A near-black CTA vanishes against a dark scrim, so inside the cover the
   button inverts: light fill, dark text. Same idea, opposite ground. */
.cover.has-video .btn-primary{
  background:var(--cover-ink); border-color:var(--cover-ink); color:#161614;
}
.cover.has-video .btn-primary:hover{
  background:#FFFFFF; border-color:#FFFFFF; color:#161614;
}

/* Required disclosure. It sits on the footage it describes and stays legible —
   it is a regulatory statement, not a caption to be styled into invisibility. */
.cover-disc{
  margin:36px 0 0;
  font-family:var(--font-mono);
  font-size:.68rem; line-height:1.5; letter-spacing:.02em;
  color:rgba(251,248,240,0.72);
  border-left:2px solid rgba(251,248,240,0.4);
  padding-left:10px;
  max-width:62ch;
}

@media (max-width:900px){
  .cover.has-video{min-height:auto;}
  .cover.has-video .wrap{padding-top:48px; padding-bottom:36px;}
  .cover-scrim{
    background:
      linear-gradient(rgba(9,20,14,0.9) 0%, rgba(9,20,14,0.86) 60%, rgba(9,20,14,0.93) 100%);
  }
}

/* Reduced motion: hold the poster frame instead of playing. The scrim, the
   contrast and the disclosure are all unchanged, so nothing about the meaning
   of the section depends on the video running. */
@media (prefers-reduced-motion: reduce){
  .cover-media video{display:none;}
  .cover-media{
    background-image:url(/assets/video/hero-loop.jpg);
    background-size:cover;
    background-position:center;
  }
}


/* ===== Illustration cards ===== */
.card .elev-thumb{height:150px;}
img.elev-thumb{width:100%; height:150px; object-fit:cover; object-position:center 45%;}
.bfig-hero img{max-width:none;}

/* Stamps: the dashed circles read as clip-art next to the new type. Same idea —
   a row of verifiable facts — set as a proper stat rule instead. */
.stamps{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(160px,1fr));
  gap:0; padding:0; border-top:1px solid var(--line); border-bottom:1px solid var(--line);
}
.stamp{
  width:auto; height:auto; border-radius:0; border:0; transform:none;
  display:block; text-align:left; padding:26px 28px 24px;
}
.stamp + .stamp{border-left:1px solid var(--line);}
.stamp:nth-child(n){transform:none; border-color:var(--line);}
.stamp b{
  display:block; font-family:var(--font-display); font-weight:700;
  font-size:2.1rem; line-height:1; letter-spacing:-0.03em; color:var(--ink);
  text-transform:none; padding:0;
}
.stamp b .sl{
  display:block; font-family:var(--font-mono); font-weight:400;
  font-size:.68rem; letter-spacing:.11em; text-transform:uppercase;
  color:var(--ink-faint); margin-top:9px; line-height:1.4;
}
@media (max-width:620px){
  .stamp{padding:20px 22px;}
  .stamp b{font-size:1.7rem;}
  .stamp:nth-child(odd){border-left:0;}
}
.statband{background:var(--paper-raised);}
.wrap.stamps{max-width:1180px; margin:0 auto;}
.thumbtag.tt-ill{background:var(--accent-racing);}
.elev-thumb img{display:block; width:100%; height:150px; object-fit:cover; object-position:center 45%;}

/* Checkboxes keep UA styling, so they render as a stark white box on a dark
   palette. accent-color hands them the theme's CTA colour in one line. */
input[type=checkbox], input[type=radio]{accent-color:var(--accent-cta);}

/* ===========================================================================
   Background texture and motion

   Generated atmosphere textures, used as material rather than imagery: each
   sits at single-digit opacity behind content, so it reads as the grain of the
   page rather than as a picture of anything. Nothing here depicts a real
   building or unit, which is why none of it needs — or gets — a property
   disclosure.

   Everything in this section is decorative and `aria-hidden` in the markup,
   and every animation is switched off under prefers-reduced-motion.
   =========================================================================== */

/* Sitewide paper grain. One 140 KB file, cached for a year, at 5% over the
   page colour: enough to kill the flatness of a solid fill, not enough to
   read as a texture in its own right. */
body::before{
  content:"";
  position:fixed; inset:0; z-index:-2; pointer-events:none;
  background-image:url(/assets/img/bg/paper.webp);
  background-size:760px auto;
  opacity:.05;
  mix-blend-mode:multiply;
}
:root[data-theme="dark"] body::before,
:root:not([data-theme="light"]) body::before{opacity:.05;}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) body::before{
    mix-blend-mode:screen; opacity:.035;
  }
}

/* Section-scale material washes. Applied per section with .bgtex-*; the image
   is masked to fade out before it reaches the text, so contrast is never
   affected by it. */
.bgtex{position:relative; isolation:isolate;}
.bgtex::before{
  content:"";
  position:absolute; inset:0; z-index:-1; pointer-events:none;
  background-repeat:no-repeat;
  background-size:cover;
  background-position:center;
  opacity:.07;
  -webkit-mask-image:linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
  mask-image:linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
}
.bgtex-brick::before  {background-image:url(/assets/img/bg/brick.webp);}
.bgtex-concrete::before{background-image:url(/assets/img/bg/concrete.webp);}
.bgtex-timber::before {background-image:url(/assets/img/bg/timber.webp);}
.bgtex-window::before {background-image:url(/assets/img/bg/steel-window.webp); opacity:.10;}

/* Slow drift. A 40s cycle over a few percent of translation reads as the page
   breathing rather than as an animation — at this speed nothing draws the eye
   away from reading, which is the point. */
@keyframes bgDrift{
  from{ transform:scale(1.06) translate3d(-1.2%, -0.8%, 0); }
  to  { transform:scale(1.06) translate3d( 1.2%,  0.8%, 0); }
}
.bgtex-drift::before{
  animation:bgDrift 40s ease-in-out infinite alternate;
  will-change:transform;
}

@media (prefers-reduced-motion: reduce){
  .bgtex-drift::before{animation:none; transform:none;}
}

/* The cover gradient already drifts; keep it, but slow it down so it agrees
   with the section drift rather than running at its own tempo. */
.cover-gradient{animation-duration:34s;}
