/* ============================================================
   Total Environment Butterfly of Dreams — "Coursed"
   One hand-written stylesheet. No framework, no build step.
   ============================================================ */

/* Hanken Grotesk (SIL OFL 1.1) — the closest open substitute for the
   Neue Haas Unica Pro that Total Environment self-hosts on its own sites
   and embeds in its brochure. ONE family, wght axis 300-700, no serif.
   The latin-ext face is 19 KB and carries the rupee sign (U+20B9), which
   is load-bearing here: the price and detour tables are full of it and a
   fallback glyph mid-number reads as broken. */
@font-face{
  font-family:"Hanken Grotesk";
  font-style:normal;
  font-weight:300 700;
  font-display:swap;
  src:url("../assets/fonts/hanken-grotesk-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Hanken Grotesk";
  font-style:normal;
  font-weight:300 700;
  font-display:swap;
  src:url("../assets/fonts/hanken-grotesk-latin-ext.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ============================================================
   css/styles.css — Coursed. One hand-written sheet, no build step.
   Order: (1) tokens (2) reset (3) layout (4) components (5) overrides.
   HARD RULES, enforced by review:
   - zero box-shadow declarations
   - zero border-radius declarations except the three `--dot` circles
     and the explicit `border-radius:0` resets on UA-rounded controls
   - zero clamp(), zero backdrop-filter, zero transform on hover
   - --coral may NEVER be a colour on a light ground (2.47:1 on --lit).
     It is legal only ON --deep/--deep-2, or as a FILL under --on-coral.
   - anything that indicates STATE uses --brick (>=5.22:1 everywhere).
   ============================================================ */

:root{
  /* ---- grounds, in descent order ---------------------------- */
  --lit:#FBF8F1;          /* head of the wall: masthead, hero, overview */
  --plaster:#F4EFE5;      /* body of the wall: default course ground   */
  --recess:#E7DFCD;       /* below grade: record courses, plinth footer*/
  --deep:#221A12;         /* fired course: nav bar + closing CTA       */
  --deep-2:#2E251A;       /* nested wells inside a fired course        */
  --ground:var(--plaster);/* RE-DECLARED BY EVERY COURSE. Sticky table
                             cells and inset wells read this one var.  */

  /* ---- ink -------------------------------------------------- */
  --ink:#1F1A14;          /* headings + body on all light grounds */
  --ink-2:#4A4034;        /* lede, secondary prose, legal copy    */
  --ink-3:#5E5346;        /* micro-labels, captions, table notes  */

  /* ---- interactive, light ground ---------------------------- */
  --brick:#8A4822;        /* links, state bars, focus ring, fills */
  --brick-deep:#5E2F14;   /* the hover partner. ALWAYS darker.    */
  --on-brick:#FBF8F1;     /* mandatory ink whenever brick is a fill */

  /* ---- interactive, fired ground ---------------------------- */
  --coral:#EF7F7A;        /* THE verified TE brand colour, dark only */
  --coral-lit:#F7BDB9;    /* hover partner on dark. ALWAYS lighter.  */
  --on-coral:#221A12;     /* mandatory ink whenever coral is a fill  */
  --on-deep:#F4EFE5;      /* body text on a fired course             */
  --on-deep-2:#D8C7AA;    /* micro-labels + nav links at rest        */

  /* ---- provenance (colour is ALWAYS redundant to the word) --- */
  --filed:#3F5530;        /* FILED       — olive, hue ~95deg, sat 26% */
  --inferred:#8A4822;     /* INFERRED    — same hex as --brick        */
  --unverified:#8E2B18;   /* UNVERIFIED / NOT REGISTERED              */
  --filed-on-deep:#A9BE8E;/* FILED, on a fired course                 */

  /* ---- materials: bedding edges + hatch chips ---------------- */
  --kota:#4F5546;         /* Kota limestone, grey-green */
  --teak:#7A4A24;         /* Machine-Craft joinery      */
  --moss:#3F4A2C;         /* planting, SVG leaf strokes */

  /* ---- rules ------------------------------------------------- */
  --rule:rgba(31,26,20,.14);      /* DECORATIVE ONLY: bond line, joint void */
  --rule-mid:#7E7466;             /* content separators: table rows, FAQ, frames (>=3.45:1) */
  --rule-strong:#6E6252;          /* control boundaries: field underlines, sticky divider (>=4.48:1) */
  --rule-dark:rgba(244,239,229,.18);
  --rule-dark-strong:#857060;     /* control boundaries on --deep (3.66:1) */

  /* ---- the mortar joint (the only depth device on the site) --- */
  --joint:6px;
  --joint-shade:rgba(31,26,20,.22);
  --joint-void:rgba(111,66,38,.10);
  --joint-lip:rgba(255,255,255,.62);
  --joint-shade-dark:rgba(0,0,0,.55);
  --joint-void-dark:rgba(0,0,0,.35);
  --joint-lip-dark:rgba(239,127,122,.28);

  /* ---- SCOPED interaction tokens ------------------------------
     Every link, action and focus ring reads these four. A fired
     course redefines them. There is NO bare context selector such
     as `.course--fired a{color:...}` anywhere in this sheet —
     that equal-specificity pattern is what produced 161 invisible
     hover states across this fleet.                              */
  --link:#8A4822; --link-hover:#5E2F14;
  --fill:#8A4822; --fill-hover:#5E2F14; --on-fill:#FBF8F1;
  --focus:#8A4822;

  /* ---- geometry ---------------------------------------------- */
  --radius:0;
  --dot:50%;              /* the ONLY curve on the site: 3 x 5px marks */
  --shadow:none;

  /* ---- spacing: 4px module, brick-course multiples ------------ */
  --u:.25rem; --s1:.5rem; --s2:1rem; --s3:1.5rem;
  --s4:2rem;  --s5:3rem;  --s6:4.5rem; --s7:6rem;
  --course-pad:3.5rem;    /* STEPPED at 640/1024. No clamp anywhere. */
  --edge:1rem;            /* page gutter, one side */
  --shell:min(1360px, 100% - 2rem);
  --jamb:0rem;            /* annotation column width; 15rem at >=1024 */
  --measure:42rem;        /* prose cap, ~66ch at 17px */
  --bond:0rem;            /* half-brick offset; 4.5rem at >=1024 */
  --overhang:0rem;        /* plate crossing a joint; 2.5rem at >=1024 */
  --nav-h:3rem;

  /* ---- type --------------------------------------------------- */
  --sans:"Hanken Grotesk", Arial, "Helvetica Neue", Helvetica, sans-serif;
  --t-micro:.6875rem;  /* 11px */
  --t-cap:.75rem;      /* 12px */
  --t-small:.875rem;   /* 14px */
  --t-body:1.0625rem;  /* 17px */
  --t-lede:1.1875rem;  /* 19px -> 21px at 640 */
  --t-num:1.25rem;     /* 20px. NO numeral on this site is larger. */
  --t-h3:1.25rem;      /* 20px */
  --t-h2:1.5rem;       /* 24px -> 28 -> 32 */
  --t-h1:2.25rem;      /* 36px -> 48 -> 64 */
  --lh-body:1.647; --lh-lede:1.474; --lh-tight:1.25; --lh-h1:1.04;
  --track-micro:.02em; /* deliberately NOT the fleet's .08-.22em eyebrow */
  --ease:cubic-bezier(.2,.6,.2,1);
  --dur:150ms;

  /* ---- compatibility aliases for the fleet-injected
          related-projects <style>, which reads these var() names.
          Declaring them here themes that block with no edits to it. */
  --brand-primary:#8A4822;   /* becomes --rp-accent */
  --light-primary:#E7DFCD;
  --light-secondary:#FBF8F1;
  --dark-primary:#221A12;
  --rp-cta-ink:#FBF8F1;
  --font-body:"Hanken Grotesk", Arial, sans-serif;
  --font-headline:"Hanken Grotesk", Arial, sans-serif;
}

@media (min-width:640px){
  :root{
    --course-pad:4.5rem; --edge:1.5rem; --shell:min(1360px, 100% - 3rem);
    --t-lede:1.3125rem; --t-h2:1.75rem; --t-h1:3rem;
  }
}
@media (min-width:1024px){
  :root{
    --course-pad:6rem; --jamb:15rem; --bond:4.5rem; --overhang:2.5rem;
    --t-h2:2rem; --t-h1:4rem;
  }
}

/* A fired course re-points the four interaction tokens. Nothing else. */
.course--fired,.course-nav{
  --ground:var(--deep);
  --link:var(--coral); --link-hover:var(--coral-lit);
  --fill:var(--coral); --fill-hover:var(--coral-lit); --on-fill:var(--on-coral);
  --focus:var(--coral);
}


/* ═══ Structure: the course, the joint, the jamb grid, the bond ═══
   This block was specified in the design's LAYOUT section rather than in any one
   component, and it is the load-bearing half: without it .course__inner has no
   shell width and every course sits flush at x=0 with its index clipped. */

.course{position:relative}

/* The joint is the ONLY depth device on the site — no shadows, no radii. It must
   be ABSOLUTELY positioned at the seam: a block-level ::before would be laid
   inside the course's 3.5-6rem padding and float in whitespace below the join. */
.course + .course::before,
.course + .plinth::before{
  content:"";position:absolute;top:0;inset-inline:0;height:var(--joint);z-index:2;
  pointer-events:none;
  background:linear-gradient(180deg,
    var(--joint-shade) 0 1px,
    var(--joint-void)  1px calc(var(--joint) - 1px),
    var(--joint-lip)   calc(var(--joint) - 1px) var(--joint));
}
.course--fired + .course::before,
.course + .course--fired::before,
.plinth::before{
  background:linear-gradient(180deg,
    var(--joint-shade-dark) 0 1px,
    var(--joint-void-dark)  1px calc(var(--joint) - 1px),
    var(--joint-lip-dark)   calc(var(--joint) - 1px) var(--joint));
}

/* The grade crossing — once per page, where the page moves from project to record. */
.course--grade::before{
  height:17px;
  background:
    linear-gradient(180deg,var(--ink) 0 3px,transparent 3px 17px),
    repeating-linear-gradient(45deg,var(--ink) 0 1px,transparent 1px 7px);
}

.course__inner{
  width:var(--shell);margin-inline:auto;position:relative;
  padding-block:var(--course-pad);
  display:grid;grid-template-columns:minmax(0,1fr);row-gap:var(--s4);
}
.course__inner>*{min-width:0}
.course__main>*{min-width:0}
.prose{max-width:var(--measure)}

@media (min-width:1024px){
  .course__inner{grid-template-columns:minmax(0,var(--jamb)) minmax(0,1fr);column-gap:2.5rem}
  .course__head{grid-column:1;position:sticky;top:calc(var(--nav-h) + 1rem);align-self:start}
  .course__main{grid-column:2}
  /* The bond: the half-brick offset, applied by an EXPLICIT class. Never
     :nth-of-type — that counts across all <section> siblings and drifts the
     moment a hero or CTA course is interleaved. */
  .course--bond .course__inner{padding-inline-start:var(--bond)}
  .course--bond .course__inner::before{
    content:"";position:absolute;inset-block:var(--course-pad);inset-inline-start:0;
    width:1px;background:var(--rule);
  }
}
@media (max-height:640px){.course__head{position:static}}

/* Overflow guards. `clip` not `hidden`: hidden kills position:sticky on both the
   nav and the jamb. */
html,body{overflow-x:clip}
img,svg,table,iframe{max-width:100%}
.plate-field>*,.ledger>*,.dim>*{min-width:0}

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

/* The hero drawing. The section is 37 floors tall, so left unconstrained the SVG
   scales to its viewBox ratio and renders 1704px high. Cap it and let it scroll
   with the copy instead. */
.hero__drawing{margin:0;display:flex;flex-direction:column;gap:var(--s2);align-items:center}
.elevation{width:auto;max-width:100%;height:auto;max-height:min(78vh,640px);color:var(--ink-2)}
@media (max-width:1023px){.elevation{max-height:52vh}}

/* ═══ Global reset, base type, links, focus, selection ═══ */
*,*::before,*::after{box-sizing:border-box}
*{margin:0;padding:0}
[hidden]{display:none!important}          /* #form-message is hidden by ATTRIBUTE; this stops any display rule defeating it */
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;overflow-x:clip}
body{overflow-x:clip;background:var(--plaster);color:var(--ink);
  font:400 var(--t-body)/var(--lh-body) var(--sans);
  font-synthesis-weight:none;text-rendering:optimizeLegibility}
img,svg,video{display:block;max-width:100%;height:auto}
table{max-width:100%}
p,li,td,th,dd,figcaption{overflow-wrap:break-word;hyphens:manual}
h1,h2,h3{text-wrap:balance}
h1{font:300 var(--t-h1)/var(--lh-h1) var(--sans);letter-spacing:-.03em}
h2{font:500 var(--t-h2)/var(--lh-tight) var(--sans);letter-spacing:-.015em}
h3{font:500 var(--t-h3)/1.4 var(--sans);letter-spacing:-.005em}
strong{font-weight:700;color:inherit}
.num,.schedule,.dim__v,.datum__v,.manifest__v,.faq-item__n,.gauge__nums{font-variant-numeric:tabular-nums lining-nums}

/* --- links: read the SCOPED tokens only. No context selector. --- */
a{color:var(--link);text-decoration:underline;text-decoration-thickness:1px;
  text-underline-offset:.2em;transition:color var(--dur) var(--ease),text-decoration-thickness var(--dur) var(--ease)}
a:hover{color:var(--link-hover);text-decoration-thickness:2px}
a:focus-visible,button:focus-visible,summary:focus-visible,input:focus-visible,
textarea:focus-visible,[tabindex]:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
::selection{background:var(--coral);color:var(--on-coral)}

/* --- micro-label, used everywhere an annotation is needed --- */
.micro{font-size:var(--t-micro);line-height:1.4545;font-weight:500;
  text-transform:uppercase;letter-spacing:var(--track-micro);color:var(--ink-3)}

/* --- ground classes. Each sets --ground for sticky cells/wells --- */
.course--lit{--ground:var(--lit);background:var(--lit)}
.course--plaster{--ground:var(--plaster);background:var(--plaster)}
.course--recess{--ground:var(--recess);background:var(--recess)}
.course--fired{background:var(--deep);color:var(--on-deep)}
.course--fired .micro,.course--fired .course__index{color:var(--on-deep-2)}

/* --- CSS-only jaali screen: TE's verified perforated terracotta
       lattice. Texture, never a border. Fired courses only. --- */
.jaali{position:absolute;inset:0;pointer-events:none;
  background:
    repeating-linear-gradient(90deg,transparent 0 22px,rgba(239,127,122,.07) 22px 23px),
    repeating-linear-gradient(0deg,transparent 0 22px,rgba(239,127,122,.05) 22px 23px)}

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

/* ═══ Masthead (title block) + brand lockup ═══ */
/* The mark is decorative: the wordmark text is right beside it, so
   alt="" title="" (both required to be byte-identical) keeps the link's
   accessible name clean. THE NEWLINE BETWEEN THE TWO BRAND SPANS IS A
   LOAD-BEARING WHITESPACE TEXT NODE — adjacent block spans concatenate
   with no space and corrupt the accessible name. Do not minify it away. */
.masthead{background:var(--lit);--ground:var(--lit)}
.masthead .masthead__inner{width:var(--shell);margin-inline:auto;
  padding-block:1rem;display:flex;flex-wrap:wrap;gap:var(--s2) var(--s4);
  align-items:flex-end;justify-content:space-between}
.masthead__inner>*{min-width:0}
.brand{display:flex;align-items:center;gap:.625rem;text-decoration:none;color:var(--ink)}
.brand:hover{color:var(--brick-deep);text-decoration:none}
.brand__mark{width:26px;height:26px;border-radius:0}
.brand__lock{display:block}
.brand__name{display:block;font-size:.9375rem;font-weight:500;line-height:1.2}
.brand__project{display:block;font-size:var(--t-micro);font-weight:500;
  text-transform:uppercase;letter-spacing:var(--track-micro);color:var(--ink-3);line-height:1.4545}
.masthead__meta{display:flex;flex-wrap:wrap;gap:.25rem 1.25rem;text-align:right;justify-content:flex-end}
.masthead__flag{color:var(--unverified)}
@media (max-width:639px){.masthead__meta{text-align:left;justify-content:flex-start}}

/* ═══ Nav — the soldier course (sticky, dark) + JS-free mobile scroller ═══ */
/* 11 hrefs, exactly matching the 11 SiteNavigationElement schema nodes.
   No logo, no CTA pill, no blur, no shadow, no hamburger, no drawer,
   no JS. Below 1024 the SAME bar becomes a contained horizontal
   scroller with a VISIBLE thin scrollbar as the affordance — there is
   deliberately no mask-image fade, because fading real link text toward
   the ground drops it below 4.5:1 at the edge. */
.course-nav{position:sticky;top:0;z-index:30;background:var(--deep);
  border-block:1px solid var(--rule-dark-strong)}
.course-nav__list{width:var(--shell);margin-inline:auto;list-style:none;
  display:flex;align-items:stretch;min-height:var(--nav-h);
  overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x proximity;
  scrollbar-width:thin;scrollbar-color:var(--rule-dark-strong) var(--deep)}
.course-nav__list::-webkit-scrollbar{height:4px}
.course-nav__list::-webkit-scrollbar-thumb{background:var(--rule-dark-strong)}
.course-nav__list::-webkit-scrollbar-track{background:var(--deep)}
.course-nav li{scroll-snap-align:start;display:flex}
.course-nav li + li{border-inline-start:1px solid var(--rule-dark-strong)}
.course-nav a{display:flex;align-items:center;gap:.4rem;white-space:nowrap;
  padding:0 .875rem;min-height:var(--nav-h);
  font-size:var(--t-micro);font-weight:500;text-transform:uppercase;
  letter-spacing:var(--track-micro);color:var(--on-deep-2);text-decoration:none;
  border-bottom:2px solid transparent}
.course-nav__n{color:var(--coral)}
.course-nav a:hover{color:var(--coral);text-decoration:none;border-bottom-color:var(--coral)}
.course-nav a[aria-current="page"]{color:var(--on-deep);border-bottom-color:var(--coral)}
.course-nav a[aria-current="page"] .course-nav__n{color:var(--on-deep)}
.course-nav a:focus-visible{outline:2px solid var(--coral);outline-offset:-2px}
.course-nav__end{margin-inline-start:auto}
@media (max-width:1023px){.course-nav__end{margin-inline-start:0}}

/* ═══ Breadcrumb (visible, subpages only — 1/49 in the fleet) ═══ */
/* Sits BETWEEN the nav and the first <section>, never inside one — its
   hrefs must not pour into a section block and skew rule scoring.
   Mirrors the BreadcrumbList JSON-LD every non-index page already ships.
   Separators are ::before, so no aria-hidden <li> is needed. */
.crumbs{background:var(--lit);border-bottom:1px solid var(--rule-mid)}
.crumbs__list{width:var(--shell);margin-inline:auto;list-style:none;
  display:flex;flex-wrap:wrap;gap:.5rem;padding-block:.625rem;
  font-size:var(--t-micro);font-weight:500;text-transform:uppercase;
  letter-spacing:var(--track-micro);color:var(--ink-3)}
.crumbs li + li::before{content:"/";margin-inline-end:.5rem;color:var(--rule-mid)}
.crumbs a{color:var(--link);text-decoration:none;border-bottom:1px solid currentColor}
.crumbs a:hover{color:var(--link-hover)}
.crumbs [aria-current="page"]{color:var(--ink)}

/* ═══ Hero — the elevation title sheet (no photograph) ═══ */
/* NO PHOTOGRAPH, no scrim, no 50/50 photo split — the two hero ideas
   that account for all 49 fleet sites. LCP is the H1: plain text on a
   flat ground, never gated behind a reveal.
   The page-updated <p> keeps `class` as its ONLY attribute with the
   exact value `page-updated` (the sync regex is literal) and is styled
   solely through the descendant selector below. */
.hero{overflow:hidden}
.hero__datums{position:absolute;inset:0;pointer-events:none;z-index:0;color:var(--ink)}
.datum{position:absolute;inset-inline:0;height:0;border-top:1px solid var(--rule-mid)}
.datum--grade{border-top-width:2px;border-top-color:var(--ink)}
.datum__v{position:absolute;top:-1.15rem;inset-inline-start:0;
  padding-inline-start:max(var(--edge),calc((100% - 1360px) / 2));
  font-size:var(--t-micro);font-weight:500;letter-spacing:var(--track-micro);
  text-transform:uppercase;color:var(--ink-3)}
.datum__below{position:absolute;inset-inline:0;border-top:0}
/* Tuned ONCE against the rendered SVG at 1280px. The drawing has a fixed
   aspect-ratio, so the proportions hold while the drawing is the tallest
   element in the course. */
.datum--1{top:6%}.datum--2{top:14%}.datum--3{top:17%}
.datum--4{top:78%}.datum--5{top:84%}.datum__below{top:86%}
@media (max-width:1023px){.hero__datums{display:none}}

.hero .course__inner{position:relative;z-index:1}
@media (min-width:1024px){
  .hero__main{display:grid;grid-template-columns:minmax(0,var(--measure)) minmax(0,1fr);
    column-gap:2.5rem;align-items:end}
}
.hero__copy>*+*{margin-block-start:var(--s3)}
/* Small text is set on an OPAQUE ground so a datum line never runs
   through a paragraph. The H1 is deliberately left to sit on the ruled
   field — 64px/300 over a 1px hairline reads as writing on ruled paper. */
.hero__lede,.ledger,.stamp{position:relative;z-index:1;background:var(--lit)}
.stamp{display:inline-block;padding-block:.4rem;border-block:1px solid var(--rule-mid);
  font-size:var(--t-micro);font-weight:500;text-transform:uppercase;
  letter-spacing:var(--track-micro);color:var(--ink-3)}
.lede{font-size:var(--t-lede);line-height:var(--lh-lede);color:var(--ink-2);max-width:var(--measure)}
.hero__drawing{color:var(--ink)}
.hero__drawing svg{width:100%;height:auto;aspect-ratio:220/660}
.elevation__dim{font:500 9px var(--sans);fill:var(--ink-3);letter-spacing:.02em}
.hero__drawing figcaption{margin-block-start:var(--s2)}
.page-updated{font-size:var(--t-micro);font-weight:500;text-transform:uppercase;
  letter-spacing:var(--track-micro);color:var(--ink-3)}

/* ═══ Action ledger (replaces the filled + outline CTA pair) ═══ */
/* THREE equal ruled rows separated by mortar joints. No fill, no pill,
   no primary/secondary hierarchy — 49/49 fleet sites ship exactly two
   side-by-side CTAs, one filled and one outline, drawn from the same
   phrasebook. Each row is >=72px tall: a far larger tap target than the
   pill it replaces. The left bar is a ::before, NOT a border, so
   widening it on hover causes zero reflow. */
.ledger{list-style:none;max-width:var(--measure)}
.ledger li + li{border-top:var(--joint) solid transparent;
  background-image:linear-gradient(180deg,var(--joint-shade) 0 1px,var(--joint-void) 1px 5px,var(--joint-lip) 5px 6px);
  background-repeat:no-repeat;background-size:100% var(--joint);background-position:0 0;
  background-origin:border-box;background-clip:border-box}
.ledger__row{position:relative;display:grid;
  grid-template-columns:2.5rem minmax(0,1fr) 1.5rem;align-items:center;
  column-gap:var(--s2);min-height:4.5rem;padding:1rem 1rem 1rem 1.5rem;
  border-radius:0;text-decoration:none;background:var(--row-bg,var(--lit));
  transition:background-color var(--dur) var(--ease),color var(--dur) var(--ease)}
.ledger__row::before{content:"";position:absolute;inset-block:0;inset-inline-start:0;
  width:4px;background:var(--row-bar,var(--brick));transition:width var(--dur) var(--ease),background-color var(--dur) var(--ease)}
.ledger__k{font-size:var(--t-micro);font-weight:500;text-transform:uppercase;
  letter-spacing:var(--track-micro);color:var(--row-k,var(--brick));font-variant-numeric:tabular-nums}
.ledger__v{font-size:var(--t-body);font-weight:500;color:var(--row-v,var(--ink))}
.ledger__arrow{color:var(--row-a,var(--ink-3));justify-self:end}
/* HOVER: background and BOTH foregrounds are set in the same block, so a
   half-applied rule can never land foreground on background. */
.ledger__row:hover,.ledger__row:focus-visible{background:var(--fill);color:var(--on-fill)}
.ledger__row:hover .ledger__k,.ledger__row:hover .ledger__v,.ledger__row:hover .ledger__arrow,
.ledger__row:focus-visible .ledger__k,.ledger__row:focus-visible .ledger__v,
.ledger__row:focus-visible .ledger__arrow{color:var(--on-fill)}
.ledger__row:hover::before{width:10px;background:var(--fill-hover)}
.ledger__row:active{background:var(--fill-hover);color:var(--on-fill)}
/* On a fired course the same markup re-reads SCOPED TOKENS — never a context
   selector.
   This block previously read `.course--fired .ledger__row{background:var(--deep-2)}`,
   which is specificity (0,2,0): exactly equal to `.ledger__row:hover` and LATER
   in the sheet, so it won the background while the hover rule's
   `color:var(--on-fill)` still applied to the children. Near-black #221A12 on
   #2E251A — a MEASURED 1.14:1 invisible hover, the same defect that was swept
   out of 83 sites across this fleet. Token defaults keep the resting rule at
   (0,1,0) so :hover always wins. */
.course--fired{
  --row-bg:var(--deep-2);
  --row-k:var(--coral);
  --row-v:var(--on-deep);
  --row-a:var(--on-deep-2);
  --row-bar:var(--coral);
}

/* ═══ Course head (the jamb): index, H2, note ═══ */
/* 48/49 fleet sites centre an eyebrow + H2 + 60ch subtitle over the body,
   10–14 times per page. Here every H2 hangs left in a sticky jamb, and
   the jamb carries the copy's own qualifications as margin notes — which
   is what makes the asymmetric track load-bearing rather than decorative. */
.course__head>*+*{margin-block-start:var(--s2)}
.course__index{font-size:var(--t-micro);font-weight:500;letter-spacing:var(--track-micro);
  text-transform:uppercase;color:var(--ink-3);font-variant-numeric:tabular-nums;
  padding-block-end:.5rem;border-bottom:1px solid var(--rule-mid)}
.course__head h2{color:var(--ink)}
.course--fired .course__head h2{color:var(--on-deep)}
.note{max-width:26rem;padding-inline-start:.75rem;border-inline-start:2px solid var(--brick);
  font-size:var(--t-small);line-height:1.7143;color:var(--ink-2)}
.note__label{display:block;font-size:var(--t-micro);font-weight:500;
  text-transform:uppercase;letter-spacing:var(--track-micro);color:var(--brick);
  margin-block-end:.25rem}
.course--fired .note{border-inline-start-color:var(--coral);color:var(--on-deep-2)}
.course--fired .note__label{color:var(--coral)}
@media (max-width:1023px){
  /* the jamb inlines above the block it annotates, keeping its rule */
  .course__head{padding-block-end:var(--s3);border-bottom:1px solid var(--rule-mid)}
  .note{max-width:none}
}

/* ═══ Prose body + sister links ═══ */
/* Sister-link contract: 1–2 per core page, ALWAYS inside a <p> in
   .prose, never in a list, nav, footer, the hero course or the CTA
   course; anchor text byte-equal to the target's displayName. No
   wrapper class or id on this site may contain the tokens hero, cta,
   contact, source, reference, linking-notes, related-project(s),
   explore-card, nav-menu, site-header, site-footer — which is why the
   citation block is `.note` and the button block is `.ledger`.
   NEVER link to any totalenvironmentsarjapur* domain: te-sarjapur and
   te-butterfly-of-dreams are in EXCLUDED_SISTER_PAIRS (same parcel). */
.prose{max-width:var(--measure)}
.prose>*+*{margin-block-start:var(--s3)}
.prose h3{margin-block-start:var(--s4)}
.prose ul,.prose ol{padding-inline-start:1.25rem}
.prose li+li{margin-block-start:.5rem}
.prose ::marker{color:var(--brick)}
.course--fired .prose{color:var(--on-deep)}
.course--fired .prose ::marker{color:var(--coral)}

/* ═══ Metric block — the dimension string (replaces the stat strip) ═══ */
/* 43/49 fleet sites render these six facts as giant-numeral-over-tiny-caps
   tiles. Here they are a measured drawing's dimension string: values ABOVE
   a real dimension line with arrow terminators and ticks, units BELOW it.
   HARD DISCIPLINE RULE: no numeral anywhere on this site is set above
   --t-num (20px). The largest type on the page is the H1; emphasis is
   carried by the drawn line, not by numeral size.
   The block is a <ol> inside a <div class="course">, NOT a <section>, so
   it is invisible to section scoring and can never hijack a rule slot. */
.dim{list-style:none;position:relative;display:grid;
  grid-template-columns:repeat(6,minmax(0,1fr));
  column-gap:var(--s2);padding-block:2.25rem 1.25rem}
.dim::before{content:"";position:absolute;inset-inline:0;top:50%;height:1px;background:var(--rule-mid)}
.dim::after{content:"";position:absolute;inset-inline-end:0;top:50%;
  width:8px;height:8px;transform:translateY(-50%);background:var(--rule-mid);
  clip-path:polygon(0 0,100% 50%,0 100%)}
.dim__item{position:relative;display:grid;row-gap:1.25rem;padding-inline-end:.5rem}
.dim__item::before{content:"";position:absolute;inset-inline-start:0;top:50%;
  width:1px;height:10px;transform:translateY(-50%);background:var(--rule-mid)}
.dim__v{font-size:var(--t-num);font-weight:500;color:var(--ink);line-height:1.2}
.dim__u{font-size:var(--t-micro);font-weight:500;text-transform:uppercase;
  letter-spacing:var(--track-micro);color:var(--ink-3)}
@media (max-width:1023px){.dim{grid-template-columns:repeat(3,minmax(0,1fr));row-gap:var(--s4)}}
@media (max-width:639px){
  /* rotates into a vertical dimension CHAIN — no truncation, no overflow */
  .dim{grid-template-columns:minmax(0,1fr);row-gap:var(--s2);padding:0 0 0 1.25rem}
  .dim::before{inset-inline:0 auto;inset-block:0;top:auto;width:1px;height:auto}
  .dim::after{inset-inline-start:-3.5px;inset-inline-end:auto;top:auto;bottom:0;
    transform:none;clip-path:polygon(50% 100%,0 0,100% 0)}
  .dim__item{grid-template-columns:6rem minmax(0,1fr);align-items:baseline;row-gap:0;column-gap:.75rem;padding-block:.5rem}
  .dim__item::before{inset-inline-start:-1.25rem;top:1.1rem;width:10px;height:1px;transform:none}
}

/* ═══ Provenance tag (FILED / INFERRED / UNVERIFIED) ═══ */
/* Square 1px-bordered chips, never coloured pills. Colour is ALWAYS
   redundant to the literal word — the word is the indicator, the hue is
   reinforcement. This is the component that makes the page read as an
   audit rather than a restyled brochure, and it is the right granularity
   for a project with reraId:null, no sanctioned plan, and a 4 BHK band
   the copy itself calls unsupported. */
.tag{display:inline-block;padding:.125rem .375rem;border:1px solid currentColor;
  border-radius:0;font-size:var(--t-micro);font-weight:500;line-height:1.4545;
  text-transform:uppercase;letter-spacing:var(--track-micro);white-space:nowrap}
.tag--filed{color:var(--filed)}
.tag--inferred{color:var(--inferred)}
.tag--unverified{color:var(--unverified)}
.course--fired .tag--filed{color:var(--filed-on-deep)}
.course--fired .tag--inferred,.course--fired .tag--unverified{color:var(--coral)}

/* ═══ Data table — the schedule (must not overflow 375px) ═══ */
/* The primary object of this site — up to 15 tables per page at up to 6
   columns. NO zebra striping (the corporate-table tell, and the thing
   that produces a visible seam down a sticky label column). Rules on the
   horizontal only; no outer box, no vertical rules, no radius, no shadow.
   The sticky first cell reads --ground, which EVERY course declares, so
   it can never paint the wrong plaster. */
.table-wrap{overflow-x:auto;overscroll-behavior-x:contain;max-width:100%;
  scrollbar-width:thin;scrollbar-color:var(--rule-mid) var(--ground)}
.table-note{display:none;margin-block-end:.5rem}
@media (max-width:1023px){.schedule--sticky ~ .table-note,.table-wrap>.table-note{display:block}}
.schedule{width:100%;border-collapse:collapse;border-radius:0}
.schedule--sticky{min-width:34rem}
.schedule__cap{caption-side:top;text-align:left;padding-block-end:.5rem;color:var(--ink-3)}
.schedule th,.schedule td{padding:.75rem 1rem;text-align:left;vertical-align:top}
.schedule th:first-child,.schedule td:first-child{padding-inline-start:0}
.schedule thead th{font-size:var(--t-micro);font-weight:500;text-transform:uppercase;
  letter-spacing:var(--track-micro);color:var(--ink);white-space:nowrap;
  border-bottom:2px solid var(--ink)}
.schedule tbody th,.schedule tbody td{font-size:var(--t-small);line-height:1.7143;
  border-bottom:1px solid var(--rule-mid)}
.schedule tbody th{font-weight:500;color:var(--ink)}
.schedule .num{text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums lining-nums}
/* ROW HOVER: the ground does NOT change at all — structurally removing
   the contrast risk on a 122-row schedule. A 3px --brick bar (>=5.22:1
   on every light ground) rises at the row's leading edge instead. Coral
   is 1.98:1 on --recess and is therefore NEVER used as a state bar. */
.schedule tbody th:first-child,.schedule tbody td:first-child{position:relative}
.schedule tbody tr>:first-child::before{content:"";position:absolute;inset-block:0;
  inset-inline-start:-6px;width:0;background:var(--brick);transition:width var(--dur) var(--ease)}
.schedule tbody tr:hover>:first-child::before{width:3px}
.schedule--sticky th:first-child,.schedule--sticky td:first-child{
  position:sticky;inset-inline-start:0;z-index:1;background:var(--ground);
  padding-inline-start:0;border-inline-end:1px solid var(--rule-strong)}
@media (max-width:639px){
  /* stacked mode: ONLY for genuinely 2–3 column tables, and every <td>
     must carry data-label or the labels silently vanish. Anything wider
     stays on .schedule--sticky and scrolls. */
  .schedule--stack thead{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
  .schedule--stack tr{display:block;border-top:1px solid var(--rule-mid);padding-block:.75rem}
  .schedule--stack tbody td{display:grid;grid-template-columns:8rem minmax(0,1fr);
    gap:.5rem;border:0;padding:.25rem 0}
  .schedule--stack tbody td::before{content:attr(data-label);font-size:var(--t-micro);
    font-weight:500;text-transform:uppercase;letter-spacing:var(--track-micro);color:var(--ink-3)}
  .schedule--stack .num{text-align:left}
}

/* ═══ Detour gauge (location) — the fleet's only chart ═══ */
/* Across 49 fleet sites there is not one chart, texture, pattern or
   generated graphic. This makes the copy's actual argument visible: the
   lake that looks nearest in a straight line is the farthest to drive to,
   and Muthanallur Cross inverts the other way. The bars are aria-hidden
   because the same numbers are printed in full beneath them, so no data
   is available only by colour or only by length. */
.gauge{list-style:none;max-width:var(--measure)}
.gauge__row{padding-block:var(--s2);border-top:1px solid var(--rule-mid)}
.gauge__name{font-size:var(--t-body);font-weight:500;color:var(--ink)}
.gauge__bars{display:grid;row-gap:4px;margin-block:.5rem}
.gauge__bar{display:block;height:6px;width:var(--w);min-width:2px}
.gauge__bar--air{border:1px solid var(--ink);background:transparent}
.gauge__bar--road{background:var(--brick)}
.gauge__nums{font-size:var(--t-micro);font-weight:500;text-transform:uppercase;
  letter-spacing:var(--track-micro);color:var(--ink-3)}
@media (max-width:639px){.gauge__bars{display:none}}

/* ═══ Image figure with caption (plate) + the joint-crossing plate ═══ */
/* Square by default — Total Environment's genuine brochure is
   822.047 x 822.047 pt, a verifiable format choice. The bedding edge is
   a 6px material band on the bottom only; four real materials cycle
   across a field so brick, teak, Kota and planting meet at its edges.
   EVERY <img> needs alt AND a byte-identical title. Renders are tagged
   "Visualisation", which is Total Environment's own published image
   policy and the honest label for a pre-launch with no photography. */
.plate{margin:0}
.plate__mount{background:var(--lit);border:1px solid var(--rule-mid);
  border-block-end:6px solid var(--kota);border-radius:0;padding:0}
.plate__mount--brick{border-block-end-color:var(--brick)}
.plate__mount--teak{border-block-end-color:var(--teak)}
.plate__mount--kota{border-block-end-color:var(--kota)}
.plate__mount--moss{border-block-end-color:var(--moss)}
.plate__mount img{width:100%;aspect-ratio:1/1;object-fit:cover;border-radius:0}
.plate--wide .plate__mount img{aspect-ratio:16/9}
.plate--portrait .plate__mount img{aspect-ratio:3/4}
.plate__cap{display:flex;flex-wrap:wrap;align-items:baseline;gap:.5rem;
  margin-block-start:.75rem;font-size:var(--t-small);line-height:1.7143;color:var(--ink-2)}
.plate__num{font-size:var(--t-micro);font-weight:500;text-transform:uppercase;
  letter-spacing:var(--track-micro);color:var(--ink-3);font-variant-numeric:tabular-nums}
.plate__num::after{content:"";display:inline-block;width:24px;height:1px;
  margin-inline-start:.5rem;vertical-align:middle;background:var(--rule-mid)}
/* the licensed container violation: planting overlaps the architecture */
.plate--breaks{position:relative;z-index:3;margin-block-end:calc(-1 * var(--overhang))}

/* ═══ Gallery — the plate field (hand-placed, non-modular) ═══ */
/* NOT repeat(auto-fit, minmax(...,1fr)) — 45/49 fleet sites use exactly
   that, and a tidy equal grid is the opposite geometry to a building of
   alternating cantilevers. Six hand-placed areas with varied aspect
   ratios and push/pull offsets, gutters of one mortar joint (6px) so the
   plates nearly touch like laid brick rather than floating in 2rem gaps.
   No :nth-child span rule, so there is no ragged-last-row failure mode. */
.plate-field{display:grid;gap:var(--joint);
  grid-template-columns:minmax(0,1fr);}
@media (min-width:640px){
  .plate-field{grid-template-columns:repeat(12,minmax(0,1fr))}
  .pf-a{grid-column:1/8}
  .pf-b{grid-column:8/13;margin-block-start:var(--s5)}
  .pf-c{grid-column:1/5;margin-block-start:calc(-1 * var(--s4))}
  .pf-d{grid-column:5/9}
  .pf-e{grid-column:9/13;margin-block-start:var(--s4)}
  .pf-f{grid-column:3/10;margin-block-start:var(--s2)}
}
@media (max-width:639px){.plate-field>*{margin-block-start:0!important}}
.plate-field>*{min-width:0}

/* ═══ Floor-plan card (.plan) with title block, scale bar, north arrow ═══ */
/* object-fit: CONTAIN, against the fleet's universal cover. A plan is a
   drawing and must never be cropped. The card is a drawing sheet with a
   real title block, not a white card: no radius, no shadow, no hover lift. */
.plan{margin:0}
.plan__sheet{background:var(--lit);border:1px solid var(--rule-strong);padding:1.25rem}
.plan__sheet img{width:100%;height:auto;max-height:70vh;object-fit:contain;border-radius:0}
.plan__scale{display:flex;align-items:center;gap:.75rem;margin-block-start:.75rem;color:var(--ink-3)}
.plan__scale svg{width:160px;height:18px;flex:0 0 auto}
.plan__block{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  margin-block-start:.75rem;border-top:1px solid var(--rule-mid)}
.plan__block>div{padding:.625rem 1rem .625rem 0}
.plan__block>div+div{border-inline-start:1px solid var(--rule-mid);padding-inline-start:1rem}
.plan__block dt{font-size:var(--t-micro);font-weight:500;text-transform:uppercase;
  letter-spacing:var(--track-micro);color:var(--ink-3)}
.plan__block dd{font-size:var(--t-small);font-weight:500;color:var(--ink);margin-block-start:.25rem}
@media (max-width:639px){
  .plan__sheet{padding:.75rem}
  .plan__block{grid-template-columns:minmax(0,1fr)}
  .plan__block>div+div{border-inline-start:0;border-top:1px solid var(--rule-mid);padding-inline-start:0}
}

/* ═══ Material chips + hatched sample chips (amenities / overview) ═══ */
/* 49/49 fleet sites render amenities as centred icon-over-label tiles.
   This project's amenities are quantitative, so they render as a spec
   schedule of square chips whose 3px bedding edge cycles through four
   real materials. The sample row uses genuine architectural hatch
   conventions — 45deg for brick, dot stipple for stone, banding for
   timber, a dot field for planting. Nothing is drawn anywhere in the
   fleet; this and the SVGs are the only drawn marks on any of 146 sites. */
.chips{list-style:none;display:grid;gap:var(--joint);
  grid-template-columns:repeat(2,minmax(0,1fr))}
@media (min-width:640px){.chips{grid-template-columns:repeat(4,minmax(0,1fr))}}
.chip{aspect-ratio:1/1;background:var(--lit);border:1px solid var(--rule-mid);
  border-block-end:3px solid var(--brick);border-radius:0;padding:1rem;
  display:flex;flex-direction:column;justify-content:space-between;gap:.5rem}
.chip:nth-child(4n+2){border-block-end-color:var(--teak)}
.chip:nth-child(4n+3){border-block-end-color:var(--kota)}
.chip:nth-child(4n+4){border-block-end-color:var(--moss)}
.chip__v{font-size:var(--t-num);font-weight:500;color:var(--ink);line-height:1.2}
.chip__k{font-size:var(--t-micro);font-weight:500;text-transform:uppercase;
  letter-spacing:var(--track-micro);color:var(--ink-3)}
.samples{list-style:none;display:flex;flex-wrap:wrap;gap:var(--s2)}
.samples li{display:grid;gap:.375rem;justify-items:start}
.sample{display:block;width:44px;height:44px;border:1px solid var(--ink);border-radius:0}
.sample--brick{background:repeating-linear-gradient(45deg,#8A4822 0 1.5px,#E7DFCD 1.5px 6px)}
.sample--kota{background:radial-gradient(#4F5546 .8px,#E7DFCD .9px) 0 0/5px 5px}
.sample--teak{background:repeating-linear-gradient(0deg,#7A4A24 0 1px,#E7DFCD 1px 4px)}
.sample--moss{background:radial-gradient(#3F4A2C 1.2px,transparent 1.3px) 0 0/7px 7px,#E7DFCD}

/* ═══ FAQ accordion — the raked joint ═══ */
/* Extractor pattern 4 must stay the winning pattern: <details> whose
   class token STARTS with `faq`, plus a <summary>. There must be NO
   <div class="faq-item"> anywhere on the site (that flips the winning
   pattern to 1 and breaks FAQPage.mainEntity equality on every page at
   once) and NO other <details> element anywhere (countFaqItems greps
   `<details` bare). The nav is JS-free and uses no disclosure widget,
   precisely so this stays true.
   Both marker spans are EMPTY-or-leaf and aria-hidden WITH a matching
   closing tag, and both sit INSIDE the <summary> — a sibling after the
   summary would be hidden while closed, i.e. visible only once open.
   stripDecorative removes them, so the schema Question name is exactly
   .faq-item__q. A self-closing <svg/> would NOT be stripped. */
.faqs{max-width:var(--measure)}
.faq-item{border-top:1px solid var(--rule-mid)}
.faq-item[open]{border-top-color:var(--brick)}
.faq-item summary{list-style:none;cursor:pointer;display:grid;
  grid-template-columns:2.5rem minmax(0,1fr) 1.5rem;align-items:baseline;
  column-gap:var(--s2);padding-block:1.125rem;
  font:500 var(--t-body)/1.4 var(--sans);color:var(--ink)}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary::marker{content:""}
.faq-item summary:hover{color:var(--brick-deep)}
.faq-item summary:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.faq-item__n{font-size:var(--t-micro);font-weight:500;letter-spacing:var(--track-micro);
  color:var(--ink-3);font-variant-numeric:tabular-nums}
.faq-mark{position:relative;display:block;width:14px;height:14px;justify-self:end;align-self:center}
.faq-mark::before,.faq-mark::after{content:"";position:absolute;background:var(--brick)}
.faq-mark::before{inset-inline:0;top:6px;height:1px}
.faq-mark::after{inset-block:0;left:6px;width:1px}
.faq-item[open] .faq-mark::after{display:none}
.faq-item__a{padding:0 0 1.5rem 2.5rem;background:var(--recess);
  border-inline-start:3px solid var(--brick)}
.faq-item[open] .faq-item__a{padding-block-start:.25rem}
.faq-item__a p+p{margin-block-start:var(--s2)}
@media (max-width:639px){
  .faq-item summary{grid-template-columns:2rem minmax(0,1fr) 1.25rem;column-gap:.75rem}
  .faq-item__a{padding-inline-start:1.25rem}
}

/* ═══ CTA band — the fired course ═══ */
/* ABSOLUTE CONSTRAINT: exactly ONE navigable link in this entire block,
   and it is /contact. HREF_ATTR_RE matches href on ANY tag, and
   extractInternalHrefs normalises absolute URLs to their pathname too —
   so a sister link, a back-to-top, a logo link, a course-index anchor or
   any cross-site URL inside this section fails the rule outright. Only
   #fragment, mailto:, tel: and javascript: are exempt.
   A <form> here would be legal (forms expose action=, never href=) but
   this design keeps the four-field form on contact.html only, so
   check-form has exactly one candidate.
   The h2 must contain the project name plus one of cta/contact/enquire/
   enquiry/site visit. The section id `enquire` scores +40 on the rule. */
.course--fired{position:relative;isolation:isolate}
.course--fired .course__inner{position:relative;z-index:1}
.course--fired .lede{color:var(--on-deep-2)}
.course--fired strong{color:var(--coral-lit)}   /* never inherit bold on a dark band */
.course--fired .micro{color:var(--on-deep-2)}

/* ═══ Contact form — the order sheet (contact.html) ═══ */
/* EXACTLY four fields: name (text, required), phone (tel, required),
   email (email, NO required attribute — required here is a hard error),
   message (textarea), plus a submit control. name="unit_type" and
   name="interests" are banned. #form-message is hidden by the HTML
   `hidden` ATTRIBUTE — a CSS-only display:none rule does not satisfy
   check-form, and the global [hidden]{display:none!important} stops any
   later display rule defeating it.
   VISIBLE labels above every control (not sr-only), and NO placeholder
   attributes anywhere on the site — better a11y than the fleet's
   placeholder-only pattern, and it sidesteps the placeholder scanner. */
.order{max-width:34rem;display:grid;row-gap:var(--s3)}
.order__msg{padding:.75rem 1rem;border:1px solid var(--rule-strong);
  font-size:var(--t-small);color:var(--ink)}
.order__field{display:grid;row-gap:.375rem}
.order label{font-size:var(--t-micro);font-weight:500;text-transform:uppercase;
  letter-spacing:var(--track-micro);color:var(--ink-3)}
.order__req{color:var(--brick)}
.order input,.order textarea{width:100%;min-height:44px;border:0;border-radius:0;
  background:transparent;border-bottom:1px solid var(--rule-strong);
  padding:.625rem 0;font:400 var(--t-body)/1.4 var(--sans);color:var(--ink);
  transition:border-color var(--dur) var(--ease),background-color var(--dur) var(--ease)}
.order textarea{resize:vertical}
.order input:focus-visible,.order textarea:focus-visible{
  background:var(--recess);border-bottom-color:var(--ink);border-bottom-width:2px;
  padding-block-end:calc(.625rem - 1px);   /* keeps the box height stable */
  outline:2px solid var(--focus);outline-offset:2px}
.order input:user-invalid,.order textarea:user-invalid{border-bottom-color:var(--unverified)}
.order__submit{min-height:56px;padding:1rem 1.5rem;border:1px solid var(--brick);
  border-radius:0;background:var(--fill);color:var(--on-fill);
  font:500 var(--t-body)/1.4 var(--sans);cursor:pointer;text-align:left;
  display:flex;justify-content:space-between;gap:var(--s2);
  transition:background-color var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.order__submit:hover{background:var(--fill-hover);border-color:var(--fill-hover);color:var(--on-fill)}
.order__submit:focus-visible{outline:2px solid var(--focus);outline-offset:2px}

/* ═══ Footer — the plinth (light, inverting the fleet's dark footer) ═══ */
/* Column titles MUST be <p class="footer-heading">; an <h4>/<h5>/<h6>
   inside <footer> is a hard error. The compliance strip is the direct
   analogue of Total Environment's own brochure page explaining its image
   policy, and it is the ONLY centred text on the site.
   Light plinth + dark soldier-course nav inverts the fleet's tonal
   silhouette at both ends (49/49 are light nav over dark footer). */
.plinth{position:relative;background:var(--recess);--ground:var(--recess)}
.plinth::before{content:"";position:absolute;top:0;inset-inline:0;height:var(--joint);
  background:linear-gradient(180deg,var(--joint-shade-dark) 0 1px,var(--joint-void-dark) 1px 5px,var(--joint-lip-dark) 5px 6px)}
.plinth__inner{width:var(--shell);margin-inline:auto;padding-block:var(--s6) var(--s4);
  display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s4)}
@media (min-width:640px){.plinth__inner{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1024px){.plinth__inner{grid-template-columns:repeat(4,minmax(0,1fr))}}
.plinth__col ul{list-style:none}
.plinth__col li+li{margin-block-start:.5rem}
.footer-heading{font-size:var(--t-micro);font-weight:500;text-transform:uppercase;
  letter-spacing:var(--track-micro);color:var(--ink-3);
  padding-block-end:.5rem;margin-block-end:.75rem;border-bottom:1px solid var(--rule-mid)}
.plinth a{font-size:var(--t-small);text-decoration:none;border-bottom:1px solid transparent}
.plinth a:hover{border-bottom-color:currentColor}
.plinth__compliance{grid-column:1/-1;padding-block-start:var(--s3);
  border-top:1px solid var(--rule-mid);text-align:center;
  font-size:var(--t-micro);font-weight:500;text-transform:uppercase;
  letter-spacing:var(--track-micro);color:var(--ink-3)}

/* ═══ Related-projects strip — overrides only, block left structurally intact ═══ */
/* The injected <style> sits LATER in document order than css/styles.css,
   so equal-specificity overrides lose. Every override below is prefixed
   with `body ` (0,1,1 vs the block's 0,1,0).
   NEVER re-declare position, inset or z-index for .related-projects__card
   or .related-projects__body h3 a::after — that passes the validator but
   silently breaks the full-card overlay link at runtime, a defect no
   validator sees. The :root aliases (--brand-primary, --light-primary,
   --light-secondary, --dark-primary, --rp-cta-ink, --font-body,
   --font-headline, --radius) already re-theme the block with no edits. */
body .related-projects{background:var(--recess);color:var(--ink);
  padding-block:var(--course-pad)}
body .related-projects__inner{max-width:1360px}
body .related-projects__header h2{font-family:var(--sans);font-weight:500;
  font-size:var(--t-h2);letter-spacing:-.015em}
body .related-projects__grid{gap:var(--joint)}
body .related-projects__card{background:var(--lit);border:1px solid var(--rule-mid);
  border-block-end:3px solid var(--kota);border-radius:0;box-shadow:none;
  transition:background-color var(--dur) var(--ease),border-color var(--dur) var(--ease)}
body .related-projects__card:hover{transform:none;background:var(--recess);
  border-color:var(--rule-mid);border-block-end-color:var(--brick);border-block-end-width:6px}
body .related-projects__image{aspect-ratio:1/1;border-radius:0}
body .related-projects__body h3{font-family:var(--sans);font-weight:500;font-size:var(--t-h3)}
body .related-projects__body h3 a{color:var(--ink);text-decoration:none}
body .related-projects__card:hover h3 a{color:var(--brick-deep);
  text-decoration:underline;text-decoration-thickness:2px}
body .related-projects__meta{font-weight:500;letter-spacing:var(--track-micro);
  text-transform:uppercase;color:var(--ink-3)}
body .related-projects__btn{border-radius:0;font-family:var(--sans);font-weight:500}
body .related-projects__btn--primary{background:var(--brick);color:var(--on-brick);border-color:var(--brick)}
body .related-projects__btn--primary:hover{transform:none;opacity:1;
  background:var(--brick-deep);border-color:var(--brick-deep);color:var(--on-brick)}
body .related-projects__btn--secondary{border-color:var(--rule-strong);color:var(--ink)}
body .related-projects__btn--secondary:hover{background:var(--lit);
  border-color:var(--ink);color:var(--brick-deep)}

/* ═══ 404 page ═══ */
/* 404 is special-cased almost everywhere: robots must be noindex,follow
   (never index, never nofollow); no description/og/twitter required;
   check-social-meta, check-schema-standard and the FAQ minimum all skip
   it; sync-webpage-dates excludes it, so it carries NO page-updated
   block; no content-length floor; no sister links; and it must NOT be
   listed in sitemap.xml. Keep its existing managed schema block as-is.
   No FAQ, no dim string, no drawing, no CTA course — a short sheet. */
.notfound .course__inner{padding-block:var(--s7)}
.notfound h1{max-width:var(--measure)}
.notfound .lede{margin-block:var(--s3)}

/* ═══ Course index numbering + heading id convention ═══ */
/* HEADING IDS ARE NUMERIC (h-01 … h-11), never topical. aria-labelledby
   is concatenated into the attrText that section keywords are scored
   against, so aria-labelledby="location-heading" on the wrong block
   silently hands +40 to the wrong rule with no visible symptom.
   COURSE VARIANT CLASSES ARE MATERIAL NAMES ONLY — --lit, --plaster,
   --recess, --fired, --bond, --grade — never topic names, so no
   decorative class can score against a section rule.
   HEADING LEVELS run in document order across nav, hero, every course,
   the related-projects block and the footer TOGETHER. The sequence is
   h1 (hero) -> h2 (each course head) -> h3 (inside .prose) -> h2 -> ...
   The related-projects block contributes h2 then h3 per card, which is
   legal. Footer titles are <p class="footer-heading">, never headings.
   Where the fixed copy carries its own section heading in addition to
   the contract h2, demote it to <h3> with the TEXT UNCHANGED — a markup
   change, not a copy edit — and re-check the document-order sequence. */
.course__index{font-variant-numeric:tabular-nums lining-nums}

/* ==== contact-modal (fleet rollout — see tooling/add-contact-modal.mjs) ==== */
.cm-modal {
    /* Re-assert the UA's dialog centering: universal "* { margin: 0 }" resets
       (sattva/purva families and others) strip it, pinning the dialog top-left. */
    margin: auto;
    width: min(100%, 28rem);
    padding: 1rem;
    border: 0;
    background: transparent;
    overscroll-behavior: contain;
    --cm-accent: var(--brand-primary, #8A4822);
    --cm-ink: #ffffff;
}

/* Browsers without <dialog> ignore [open] and would render the form inline. */
.cm-modal:not([open]) {
    display: none;
}

/* Literal scrim: ::backdrop cannot reliably see page custom properties. */
.cm-modal::backdrop {
    background: rgba(15, 23, 42, 0.6);
}

.cm-modal__panel {
    position: relative;
    padding: 1.5rem;
    border-radius: 0.75rem;
    background: #ffffff;
    color: #1f2937;
    font-family: inherit;
    box-shadow: 0 20px 25px rgba(15, 23, 42, 0.15);
}

.cm-modal__title {
    margin: 0 0 1.25rem;
    padding-right: 2.5rem;
    font-size: 1.125rem;
    font-weight: 700;
    line-height: 1.3;
    color: #1f2937;
}

.cm-modal__close {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border: 0;
    border-radius: 0.25rem;
    background: transparent;
    color: #475569;
    cursor: pointer;
    font-size: 1.5rem;
    line-height: 1;
}

.cm-modal__close:hover {
    background: #f1f5f9;
    color: #0f172a;
}

.cm-modal__close:focus-visible {
    outline: 2px solid var(--cm-accent);
    outline-offset: 2px;
}

.cm-form {
    display: grid;
    gap: 1rem;
}

.cm-form__field {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    text-align: left;
}

.cm-form__field label {
    font-size: 0.85rem;
    font-weight: 600;
    color: #1f2937;
}

/* Form controls don't inherit fonts — font: inherit closes the gap. */
.cm-form input,
.cm-form textarea {
    width: 100%;
    min-width: 0;
    font: inherit;
    color: #1f2937;
    background: #ffffff;
    border: 1px solid #cbd5e1;
    border-radius: 6px;
    padding: 0.6rem 0.75rem;
}

.cm-form input:focus-visible,
.cm-form textarea:focus-visible {
    outline: 2px solid var(--cm-accent);
    outline-offset: 1px;
}

.cm-form textarea {
    min-height: 5.5rem;
    resize: vertical;
}

.cm-form__submit {
    border: 0;
    border-radius: 6px;
    background: var(--cm-accent);
    color: var(--cm-ink);
    cursor: pointer;
    font: inherit;
    font-weight: 600;
    padding: 0.75rem 1.5rem;
}

.cm-form__submit:hover {
    opacity: 0.92;
}

.cm-form__submit:focus-visible {
    outline: 2px solid #1f2937;
    outline-offset: 2px;
}

.cm-form__hint {
    margin: 0;
    font-size: 0.8rem;
    line-height: 1.55;
    color: #64748b;
}

.cm-form__hint a {
    color: inherit;
    text-decoration: underline;
}

/* Class-based, so it cannot fight any inline body.style.overflow use. */
body.has-modal-open {
    overflow: hidden;
}

@media (prefers-reduced-motion: no-preference) {
    .cm-modal[open] {
        animation: cm-modal-in 160ms ease-out;
    }

    .cm-modal[open]::backdrop {
        animation: cm-modal-backdrop-in 160ms ease-out;
    }
}

@keyframes cm-modal-in {
    from {
        opacity: 0;
        transform: translateY(0.5rem);
    }
}

@keyframes cm-modal-backdrop-in {
    from {
        opacity: 0;
    }
}

/* The UA placeholder colour is #757575 — 4.34:1 on --lit, just under AA. It is a
   pseudo-element, so an element walker never sees it and axe does not test it
   either; it has to be set explicitly. opacity:1 because Firefox dims
   placeholders by default. */
.order input::placeholder,
.order textarea::placeholder,
.cm-form input::placeholder,
.cm-form textarea::placeholder{color:var(--ink-3);opacity:1}

/* ═══ Classes the renderer emits that the component specs did not cover ═══
   Every one of these was flagged by an undefined-class diff (classes used in
   markup with no rule anywhere). A class with no rule ships as unstyled markup
   and no validator ever sees it — 26 fleet sites shipped green with 204 dead
   class uses. */

/* Body + title-course markers. `sheet-head` is the first course on a subpage;
   it needs no paint of its own but the hook is real, so it gets the one thing
   it does do: suppress the top joint, since nothing precedes it. */
.sheet{}
.sheet--index{}
.sheet-head .course__inner{padding-block-start:var(--s5)}

/* Structural markers read by the fleet's sister-link rewirer, not by the eye:
   `.cta` on the closing course and `.site-header` on the masthead are matched
   by BAD_BLOCK_RE so no sister link is injected into either. They intentionally
   carry no paint. */
.cta{}
.site-header{}

/* Floor-plan set — same field rhythm as the plate field, one column on mobile. */
.plan-set{display:grid;gap:var(--s4);grid-template-columns:minmax(0,1fr)}
@media (min-width:640px){.plan-set{grid-template-columns:repeat(2,minmax(0,1fr))}}

/* A single full-width drawing sheet (master plan, location map). */
.plate--sheet .plate__mount{background:var(--lit);border:1px solid var(--rule-mid)}
.plate--sheet img{width:100%;height:auto;object-fit:contain}

/* The caption's prose half; .plate__num and .plate__cap come from the spec. */
.plate__text{color:var(--ink-2)}

/* Inline per-field validation message from js/contact-form.js. Hidden by the
   [hidden] attribute until the handler clears it, so it must not be display-set
   here. --unverified is the palette's only red and is 6.05:1 on --lit. */
.field-error{display:block;margin-block-start:.35rem;font-size:var(--t-cap);
  font-weight:500;color:var(--unverified)}
.field-error[hidden]{display:none}

/* The order sheet sits in its own course on contact.html. */
.order-wrap{max-width:34rem}
