/* Security, a house at dusk: a brick Chicago two-flat, cornice at the top of the page and stoop at the bottom.
   Plates are in assets/img/trades/security/, drawn by mockups/trade-rows/src/_tex-06-security-house-at-night.mjs. Every window is .pane: the pane is the glass, box-shadow is the
   trim, ::before the lintel, ::after the sill. A .pane-lights window splits into .light children, and the
   gap between them shows as a meeting rail or a mullion, so a rail never crosses text. Text stays flat. */

/* ---------- The page is dark from the root, so overscroll and the scrollbar stay on the wall ---------- */
html { background: var(--ink); scrollbar-color: var(--porch) var(--ink); }
body {
  --ground: var(--ink);
  --fg: var(--porch);
  --fg-muted: var(--muted-night);
  --line: rgb(255 210 63 / 0.24);
  --press: var(--porch);
  --press-fg: var(--ink);
  --dot-on: var(--porch);
  --dot-off: var(--mark-muted);
  --bar-off: var(--mark-muted);

  --edge: clamp(1.25rem, 0.5rem + 3.2vw, 3.5rem);
  --pier: clamp(1.75rem, 0.5rem + 3.4vw, 3.75rem);
  --floor: clamp(4rem, 2.75rem + 3.6vw, 6rem);
  --storey: clamp(4.5rem, 3rem + 5vw, 7.5rem);
  --pane-pad: clamp(1.15rem, 0.8rem + 1.5vw, 2.25rem);

  --sash: clamp(0.25rem, 0.15rem + 0.3vw, 0.45rem);
  --trim: calc(var(--sash) + 5px);
  --rail: clamp(0.3rem, 0.2rem + 0.3vw, 0.5rem);
  --lintel-h: clamp(0.7rem, 0.45rem + 0.7vw, 1.2rem);
  --sill-h: clamp(0.8rem, 0.5rem + 0.8vw, 1.35rem);
  --ear: clamp(0.2rem, 0.05rem + 0.5vw, 0.5rem);
  --stone: url('/assets/img/trades/security/stone.svg');
  --lantern: clamp(3rem, 1rem + 5.5vw, 6.5rem);
  --entry-w: min(100% - 2 * var(--lantern) - 3rem, 74rem);
}
::selection { background: var(--porch); color: var(--ink); }

.site-footer { border-top: 0; }

/* ---------- The wall: one continuous brick layer, with no seam at a section edge ---------- */
.house {
  position: relative; isolation: isolate; overflow-x: clip;

  &::before {
    content: ''; position: absolute; inset: 0; z-index: -1;
    background:
      url('/assets/img/trades/security/weather.svg') 0 0 / 2600px 3700px,
      url('/assets/img/trades/security/brick.svg') 50% 0 / 1536px 2400px;
  }
  & section:not(.pane) { background: none; }
}

/* Type on the wall: the brick fades to clean ink behind it. */
.on-wall {
  position: relative; isolation: isolate;

  &::before {
    content: ''; position: absolute; z-index: -1; inset: -3.75rem -7rem;
    background: var(--ink);
    mask-image:
      linear-gradient(to right, transparent, rgb(0 0 0 / 0.3) 1.75rem, rgb(0 0 0 / 0.72) 3.75rem, #000 6rem, #000 calc(100% - 6rem), rgb(0 0 0 / 0.72) calc(100% - 3.75rem), rgb(0 0 0 / 0.3) calc(100% - 1.75rem), transparent),
      linear-gradient(to bottom, transparent, rgb(0 0 0 / 0.4) 1rem, rgb(0 0 0 / 0.8) 2rem, #000 3rem, #000 calc(100% - 3rem), rgb(0 0 0 / 0.8) calc(100% - 2rem), rgb(0 0 0 / 0.4) calc(100% - 1rem), transparent);
    mask-composite: intersect;
  }
}

/* ---------- A window ---------- */
.pane {
  --ground: var(--lit);
  --fg: var(--ink);
  --fg-muted: var(--muted-porch);
  --line: rgb(27 22 9 / 0.22);
  --press: var(--ink);
  --press-fg: var(--porch);
  --dot-on: var(--ink);
  --dot-off: var(--ramp-1);
  --bar-off: var(--emphasis-off);

  position: relative; z-index: 1; min-width: 0; padding: var(--pane-pad);
  background: var(--ground); color: var(--fg);
  box-shadow:
    0 0 0 var(--sash) var(--ramp-5),
    0 0 0 calc(var(--sash) + 3px) var(--ramp-3),
    0 0 0 calc(var(--sash) + 5px) var(--ramp-5);

  & p + p { margin-top: 0.85rem; }
  & ::selection { background: var(--ink); color: var(--porch); }

  /* Limestone lintel over the head, limestone sill under the foot. */
  &::before, &::after {
    content: ''; position: absolute; left: calc(-1 * (var(--trim) + var(--ear))); right: calc(-1 * (var(--trim) + var(--ear)));
    z-index: 1; pointer-events: none;
  }
  &::before {
    bottom: calc(100% + var(--trim)); height: var(--lintel-h);
    background: var(--stone) 0 0 / 320px 32px, linear-gradient(to bottom, var(--muted-night) 0 84%, var(--ramp-2) 84%);
    box-shadow: 0 0.3rem 0.4rem rgb(19 15 6 / 0.7);
  }
  &::after {
    top: calc(100% + var(--trim)); height: var(--sill-h);
    left: calc(-1 * (var(--trim) + var(--ear) * 1.5)); right: calc(-1 * (var(--trim) + var(--ear) * 1.5));
    background: var(--stone) 0 12px / 320px 32px, linear-gradient(to bottom, var(--lit) 0 18%, var(--muted-night) 18% 80%, var(--ramp-2) 80%);
    box-shadow: 0 0.55rem 0.75rem rgb(19 15 6 / 0.75);
  }
}
.pane-porch { --ground: var(--porch); }
.pane-lights {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--rail); padding: 0; background: var(--ramp-5);
}
.pane .light { position: relative; min-width: 0; margin: 0; padding: var(--pane-pad); background: var(--ground); }

/* A brick flat arch in place of the limestone over some windows: a soldier course, bricks stood on end. */
.pane-soldier::before {
  left: calc(-1 * (var(--trim) + var(--ear) * 2)); right: calc(-1 * (var(--trim) + var(--ear) * 2));
  height: clamp(1.25rem, 0.8rem + 1.1vw, 2rem);
  background: url('/assets/img/trades/security/soldier.svg') 0 0 / auto 100% repeat-x;
  box-shadow: 0 0.2rem 0.3rem rgb(19 15 6 / 0.7);
}

/* Muntins only ever sit on empty glass: a transom over a window that holds text. */
.transom {
  --n: 8;
  position: relative; height: clamp(2.25rem, 1.5rem + 2.2vw, 4rem); background-color: var(--ground);
  background-image: linear-gradient(to right, var(--ramp-5) var(--rail), transparent 0);
  background-size: calc(100% / var(--n)) 100%; background-position: calc(var(--rail) / -2) 0;
}
.transom-twelve { --n: 12; }
.transom-three { --n: 3; }

/* Type in the windows */
.wall-title { font-size: var(--t-xl); font-weight: var(--w-loud); letter-spacing: var(--track-xl); line-height: 1.02; }
.wall-title-small { font-size: var(--t-l); font-weight: var(--w-head); letter-spacing: var(--track-l); line-height: 1.08; }
.wall-lead { font-size: var(--t-m); line-height: 1.35; color: var(--muted-night); max-width: 56ch; }
.wall-note { color: var(--muted-night); max-width: 58ch; }
.pane-title { font-size: var(--t-m); font-weight: var(--w-sub); letter-spacing: -0.01em; line-height: 1.2; }
.pane-say { font-size: var(--t-l); font-weight: var(--w-head); letter-spacing: var(--track-l); line-height: 1.1; }
.pane-say-small { font-size: var(--t-m); font-weight: var(--w-sub); letter-spacing: -0.01em; line-height: 1.25; }
.pane-figure { font-family: var(--f-head); font-size: var(--t-xl); font-weight: var(--w-loud); letter-spacing: var(--track-xl); line-height: 1; font-variant-numeric: lining-nums proportional-nums; }
.pane-list {
  display: grid; gap: 0.45rem; margin-top: 0.9rem;

  & li { font-size: var(--t-body); line-height: 1.35; }
}

/* Every front stacks by default; the wall opens into twelve columns from lg. */
.front, .signature, .town-front, .hero-front, .sources-notes, .town-sample, .side-stack, .signature-part, .stair-part, .costs-part {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--floor) var(--pier); min-width: 0;
}
.front, .signature, .town-front { padding-inline: var(--edge); }
.storey { padding-top: var(--storey); }
.signature { padding-top: var(--storey); }
.signature-part + .signature-part { margin-top: var(--storey); }
.stair-floor, .town-front { padding-top: var(--storey); }

/* ---------- The cornice closes the top of the building, under the sky of the header ---------- */
.cornice {
  height: clamp(4.25rem, 3rem + 3.6vw, 6.5rem); margin-top: var(--header-h);
  background: url('/assets/img/trades/security/cornice.svg') 50% 0 / auto 100% repeat-x;
}

/* ---------- Hero: everything that opens the page sits in the big front window ---------- */
.house-hero { padding: clamp(1.5rem, 1rem + 1.5vw, 2.5rem) var(--edge) 0; }
.hero-front { align-items: start; }
.hero-window { padding-block: clamp(0.5rem, 0.2rem + 0.7vw, 1rem) var(--pane-pad); }
.hero-greeting { margin-top: 0.1rem; font-family: var(--f-head); font-size: var(--t-mega); letter-spacing: var(--track-mega); line-height: 0.98; }
.hero-hello { display: block; font-weight: var(--w-quiet); }
.hero-place { display: block; font-weight: var(--w-loud); }
.hero-offer { margin-top: 0.85rem; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.85rem 2rem; }
.hero-title { font-size: var(--t-l); font-weight: var(--w-head); letter-spacing: var(--track-l); line-height: 1.08; max-width: 18ch; }
.pane .hero-action { margin-top: 0; }
.hero-count-place { font-weight: 650; line-height: 1.2; }
.pane .hero-count-num { margin-top: 0.15rem; font-family: var(--f-head); font-size: var(--t-xl); font-weight: var(--w-loud); letter-spacing: var(--track-xl); line-height: 1; font-variant-numeric: lining-nums proportional-nums; }
.hero-count-unit { font-size: var(--t-s); color: var(--fg-muted); }
.hero-intro .light { font-size: var(--t-m); line-height: 1.32; }

/* ---------- Where leads come from: the tallest window, with small rooms stacked beside it ---------- */
.sources-table {
  & th, & td { padding-right: 1rem; }
  & tbody tr:last-child :is(th, td) { border-bottom: 0; }
}
.postcard-pane .pane-say { margin-top: 0.5rem; }

/* ---------- New homeowners: the wide window, under an eight-light transom ---------- */
.device-lead { font-size: var(--t-m); line-height: 1.3; }
.device-steps { margin-top: 0.75rem; }
.device-steps li { font-size: var(--t-xl); font-weight: var(--w-head); letter-spacing: var(--track-l); line-height: 1.04; text-wrap: balance; }
.device-tail { margin-top: 0.85rem; font-size: var(--t-m); line-height: 1.3; font-weight: 520; }

/* Upkeep: one big window, in reading order. What the money is and which homes it covers comes first and the caveat last,
   and the figures between them stay at a size that can't outrank those words. Each figure's light is as wide as its dollars. */
.upkeep-figures {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--rail); min-width: 0;

  & .light { --ground: var(--porch); }
}
.upkeep-words { line-height: 1.35; }
.pane .upkeep-note { padding-block: calc(var(--pane-pad) * 0.8); }

/* The Cooling-Off window: a mullion between the number and its sentence. */
.cooling-pane { grid-template-columns: auto minmax(0, 1fr); }
.cooling-figure { display: grid; align-items: center; padding-inline: clamp(1rem, 2vw, 2rem); }
.cooling-words { display: grid; align-items: center; }
.cooling-num { font-family: var(--f-head); font-size: var(--t-mega); font-weight: var(--w-loud); letter-spacing: var(--track-mega); line-height: 0.8; font-variant-numeric: lining-nums; }
.buyers-head .wall-note { margin-top: 0.75rem; }

/* ---------- The bay: three lights, its angle drawn in the stone. A cap above, a corbelled apron below ---------- */
.bay {
  &::before {
    height: clamp(1.6rem, 1rem + 1.6vw, 2.75rem);
    left: calc(-1 * (var(--trim) + var(--ear) * 2)); right: calc(-1 * (var(--trim) + var(--ear) * 2));
    clip-path: polygon(2.5% 0, 97.5% 0, 100% 100%, 0 100%);
    background: var(--stone) 0 0 / 320px 32px, linear-gradient(to bottom, var(--ramp-2) 0 12%, var(--muted-night) 12% 88%, var(--ramp-2) 88%);
    box-shadow: none;
  }
  &::after {
    height: clamp(2.5rem, 1.5rem + 2.6vw, 4.25rem);
    clip-path: polygon(0 0, 100% 0, 100% 32%, 97% 100%, 3% 100%, 0 32%);
    background:
      var(--stone) 0 12px / 320px 32px,
      linear-gradient(to bottom, var(--lit) 0 7%, var(--muted-night) 7% 30%, var(--ramp-2) 30% 34%, var(--ramp-3) 34%);
    box-shadow: none;
  }
}
.bay-center { --ground: var(--porch); }

/* ---------- The week chart, on the pages by place (the national guide shows a national month chart instead) ---------- */
/* The big chart's look on 26 tracks: date and count sit right on top of the bars. */
.week-bars {
  display: grid; grid-template-columns: repeat(26, minmax(0, 1fr)); column-gap: clamp(2px, 0.5vw, 0.45rem); align-items: end;
  height: clamp(17rem, 46svh, 27rem); border-bottom: 2px solid var(--fg);

  & .week-bar { display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; min-width: 0; }
  & .week-bar-date { font-family: var(--f-head); font-weight: 750; font-size: var(--t-xs); line-height: 1.1; letter-spacing: -0.02em; white-space: nowrap; }
  & .week-bar-value { margin-bottom: 0.3rem; color: var(--fg-muted); font-size: var(--t-xs); line-height: 1.2; font-variant-numeric: tabular-nums; white-space: nowrap; }
  & .week-bar-fill { width: 100%; height: calc(var(--v, 0) * 88%); background: var(--bar-off); }
  & .is-key .week-bar-fill { background: var(--fg); }
  & :is(.is-key, .is-low) .week-bar-value { color: var(--fg); font-weight: 750; }
  & .is-key { align-items: flex-end; }
}
.week-bar.is-suppressed .week-bar-fill { height: 3px; background: transparent; border-top: 2px dotted var(--fg-muted); }

/* ---------- Mail plan: the tall stair window, one light to a step. The sequence is real, so the numbers stay ---------- */
.stair-window {
  counter-reset: stair;

  & li { counter-increment: stair; line-height: 1.4; }
  & li:nth-child(even) { --ground: var(--porch); }
  & li::before {
    content: counter(stair); display: block; margin-bottom: 0.4rem;
    font-family: var(--f-head); font-size: var(--t-xl); font-weight: var(--w-loud); letter-spacing: var(--track-xl); line-height: 1; font-variant-numeric: lining-nums;
  }
}

/* ---------- Costs: the total is the loudest row ---------- */
.cost-table {
  width: 100%; max-width: none; font-size: var(--t-body);

  & tbody th { font-weight: 450; padding-right: 1.5rem; }
  & tr:last-child :is(th, td) { border-bottom: 0; }
  & tbody .cost-monthlytotal th { font-size: var(--t-m); font-weight: var(--w-sub); line-height: 1.2; vertical-align: bottom; padding-top: 1.25rem; padding-bottom: 0; }
  & tbody .cost-monthlytotal td { font-family: var(--f-head); font-size: var(--t-xl); font-weight: var(--w-loud); letter-spacing: var(--track-xl); line-height: 1; padding-top: 1.25rem; padding-right: 0; padding-bottom: 0; font-variant-numeric: lining-nums proportional-nums; }
}

/* ---------- Questions: the question in the upper sash, the answer in the lower ---------- */
.faq-wall { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--floor) var(--pier); padding-inline: var(--edge); }
.faq-panes {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--floor) var(--pier); align-items: start;

  & dt { font-size: var(--t-m); font-weight: var(--w-sub); letter-spacing: -0.01em; line-height: 1.2; text-wrap: balance; }
  & dt.light { padding-block-end: 0.9rem; }
  & dd.light { padding-block-start: 0.9rem; margin: 0; }
}

/* ---------- The sample row, the Coverage pointer and the other trades (the cities table is on the pages by place) ---------- */
.town-trades .chip-list { margin-top: 0.75rem; }
.city-table td .small { margin-left: 0.4rem; font-weight: 450; }
.city-table tbody tr:last-child td { border-bottom: 0; }

/* ---------- Closing: the lit entry at the top of the stoop, the porch light left on beside it ---------- */
.closing { padding-top: var(--storey); }
.entry { position: relative; margin-inline: auto; width: var(--entry-w); }
.closing-pane { &::after { display: none; } }
.closing-light { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: 1.25rem; }
.closing-title { font-size: var(--t-mega); font-weight: var(--w-loud); letter-spacing: var(--track-mega); line-height: 0.98; }
.closing-body { font-size: var(--t-m); line-height: 1.32; max-width: 34ch; }
.closing-pane .closing-action { margin-top: 0; }

.porch-light {
  position: absolute; left: calc(100% + var(--trim)); top: 9%;
  width: var(--lantern); aspect-ratio: 96 / 176;
  background: url('/assets/img/trades/security/lantern.svg') 0 0 / 100% 100% no-repeat;
}

.stoop {
  --tread: clamp(0.85rem, 0.55rem + 0.9vw, 1.4rem);
  --step-out: clamp(0.75rem, 0.1rem + 2.4vw, 2.5rem);
  position: relative; display: grid; justify-items: center; margin-top: var(--trim);

  /* The stoop's cheek walls, capped in stone, either side of the steps. */
  &::before, &::after {
    content: ''; position: absolute; bottom: 0; z-index: 1; width: clamp(2.5rem, 0.75rem + 4.4vw, 5rem); height: calc(var(--tread) * 4.5 + clamp(2rem, 1rem + 2.6vw, 4rem));
    background:
      linear-gradient(to bottom, var(--lit) 0 3%, var(--muted-night) 3% 9%, var(--ramp-2) 9% 11%, transparent 11%),
      var(--stone) 0 0 / 320px 32px,
      linear-gradient(to right, var(--muted-night) 0 86%, var(--ramp-2) 86%);
    box-shadow: 0 0 0.9rem rgb(19 15 6 / 0.8);
  }
  &::before { left: calc(50% - min(100%, var(--entry-w) + 6 * var(--step-out)) / 2); }
  &::after { right: calc(50% - min(100%, var(--entry-w) + 6 * var(--step-out)) / 2); transform: scaleX(-1); }

  & span {
    display: block; height: calc(var(--tread) * 1.5);
    width: min(100%, var(--entry-w) + 2 * var(--step-out));
    background:
      url('/assets/img/trades/security/joints.svg') 50% 0 / 1500px 100%,
      var(--stone) 0 6px / 320px 32px,
      linear-gradient(to bottom, var(--lit) 0 22%, var(--muted-night) 22% 86%, var(--ramp-2) 86%);
    box-shadow: 0 0.3rem 0.45rem rgb(19 15 6 / 0.6);
  }
  & span:nth-child(2) { width: min(100%, var(--entry-w) + 4 * var(--step-out)); background-position: 12% 0, 90px 6px, 0 0; }
  & span:nth-child(3) { width: min(100%, var(--entry-w) + 6 * var(--step-out)); background-position: 71% 0, 210px 6px, 0 0; }
}
.foundation { height: clamp(3.5rem, 2.5rem + 3vw, 5.75rem); background: url('/assets/img/trades/security/foundation.svg') 50% 0 / auto 100% repeat-x; }

/* ---------- Dusk: the script puts one of these on every light, and takes it away when the lamp comes on ---------- */
.lamp-off {
  position: absolute; inset: 0; z-index: 5; pointer-events: none; background-color: var(--ramp-5);

  &.is-warming { animation: lamp-warms 0.7s cubic-bezier(0.16, 1, 0.3, 1) both; }
}
@keyframes lamp-warms {
  0% { opacity: 1; background-color: var(--ramp-5); }
  30% { opacity: 0.92; background-color: var(--ramp-1); }
  100% { opacity: 0; background-color: var(--ramp-1); }
}
.porch-light { transition: filter 0.7s cubic-bezier(0.16, 1, 0.3, 1); }
.dusk .porch-light:not(.is-on) { filter: brightness(0.4); }
.reduced {
  & .lamp-off { display: none; }
  & .porch-light { transition: none; }
  &.dusk .porch-light:not(.is-on) { filter: none; }
}
@media (scripting: none) {
  .lamp-off { display: none; }
  .dusk .porch-light:not(.is-on) { filter: none; }
}
@media print {
  .lamp-off { display: none; }
  .dusk .porch-light:not(.is-on) { filter: none; }
}

/* ---------- lg and up: the full front ---------- */
@media (min-width: 992px) {
  .front, .signature, .town-front, .hero-front { grid-template-columns: repeat(12, minmax(0, 1fr)); align-items: start; }

  .hero-window { grid-column: 1 / span 8; }
  .hero-national { grid-column: 9 / -1; }
  /* One light per intro paragraph: two lights for the national guide's two paragraphs, three if a third returns
     (a third column with no paragraph showed as an empty dark pane). */
  .hero-intro { grid-column: 1 / -1; grid-template-columns: minmax(0, 5fr) minmax(0, 2.6fr); }
  .hero-intro:has(> .light:nth-child(3)) { grid-template-columns: minmax(0, 5fr) minmax(0, 4fr) minmax(0, 2.6fr); }

  .sources-title { grid-column: 1 / span 8; }
  .sources-lead { grid-column: 9 / -1; align-self: end; }
  .sources-pane { grid-column: 1 / span 8; align-self: stretch; }
  .sources-table { height: 100%; font-size: var(--t-body); }
  .sources-notes { grid-column: 9 / -1; }
  .yelp-pane { margin-right: 0; }

  .signature-part { display: contents; }

  .device-title { grid-column: 1 / span 9; }
  .device-pane { grid-column: 1 / span 8; }
  .side-stack { grid-column: 9 / -1; }

  .upkeep-window { grid-column: 1 / -1; }
  .upkeep-figures { grid-template-columns: minmax(0, 3900fr) minmax(0, 1500fr); }

  .buyers-head { grid-column: 1 / span 7; margin-top: var(--storey); }
  .buyers-lead { grid-column: 8 / -1; align-self: end; margin-top: var(--storey); }
  .bay { grid-column: 1 / -1; grid-template-columns: minmax(0, 4fr) minmax(0, 5fr) minmax(0, 3fr); margin-bottom: clamp(1.5rem, 0.5rem + 2vw, 3rem); }
  .doors-pane { grid-column: 1 / span 4; align-self: center; }
  .cooling-pane { grid-column: 5 / -1; }
  .cooling-words { font-size: var(--t-m); line-height: 1.32; }

  .months-head { grid-column: 1 / span 8; align-self: center; }
  .months-caption { grid-column: 9 / -1; }
  .months-window { grid-column: 1 / -1; }

  .stair-part { grid-column: 1 / span 5; }
  .costs-part { grid-column: 6 / -1; }
  .costs-pane { align-self: stretch; }

  .faq-wall > * { grid-area: 1 / 1; }
  .faq-title { max-width: 55%; align-self: start; }
  .faq-panes {
    grid-template-columns: repeat(12, minmax(0, 1fr)); grid-template-rows: minmax(15rem, auto);

    & > :nth-child(1) { grid-column: 8 / -1; }
    & > :nth-child(2) { grid-column: 1 / span 4; }
    & > :nth-child(3) { grid-column: 5 / -1; }
    & > :nth-child(4) { grid-column: 1 / span 9; }
    & > :is(:nth-child(3), :nth-child(4)) { grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); }
    & > :is(:nth-child(3), :nth-child(4)) dt.light { padding-block-end: var(--pane-pad); padding-inline-end: 1rem; }
    & > :is(:nth-child(3), :nth-child(4)) dd.light { padding-block-start: var(--pane-pad); padding-inline-start: 1.25rem; }
  }

  /* The sample row's head on the wall with the Coverage window beside it (the note says some fields are filled only in
     some places; the window says where), the file across the front under them, the other trades stepping in below. */
  .town-sample { display: contents; }
  .sample-head { grid-column: 1 / span 7; grid-row: 1; align-self: center; }
  .covered-pane { grid-column: 8 / -1; grid-row: 1; }
  .sample-pane { grid-column: 1 / -1; grid-row: 2; }
  .city-table { height: 100%; }
  .town-trades { grid-column: 7 / -1; grid-row: 3; }

  .closing-light { grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--gutter); align-items: end; }
  .closing-title { grid-column: 1 / -1; }
}

@media (min-width: 1200px) {
  .upkeep-figures .light:first-child { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: clamp(1.25rem, 2.5vw, 2.5rem); align-items: center; }
  .upkeep-figures .light:first-child .upkeep-words { margin-top: 0; font-size: var(--t-m); line-height: 1.3; }
}

/* All 26 counts only fit across from wide screens up; below that, the seven dated bars carry theirs. */
@media (min-width: 992px) and (max-width: 1199.98px) {
  .week-bars {
    & .week-bar:not(.is-dated) .week-bar-value { display: none; }
    & .week-bar-date { white-space: normal; text-align: center; margin-bottom: 0.1rem; }
    & .is-key { align-items: center; }
  }
}

/* Like the big chart, the weeks turn into labeled rows when the bars get too narrow to carry their dates. */
@media (max-width: 991.98px) {
  .week-bars { display: block; height: auto; border-bottom: 0; }
  .week-bars .week-bar {
    display: grid; grid-template-columns: 3.5rem minmax(0, 1fr) 2.75rem; column-gap: 0.5rem; align-items: center;
    height: auto; padding-block: 0.12rem;
  }
  .week-bars .week-bar-date { grid-column: 1; grid-row: 1; }
  .week-bars .week-bar-fill { grid-column: 2; grid-row: 1; height: 0.9rem; width: calc(var(--v, 0) * 100%); }
  .week-bars .week-bar-value { grid-column: 3; grid-row: 1; margin: 0; text-align: right; }
}

/* ---------- md: six columns, so the front stays irregular instead of falling into a stack of bands ---------- */
@media (min-width: 768px) and (max-width: 991.98px) {
  .front, .signature, .town-front, .hero-front { grid-template-columns: repeat(6, minmax(0, 1fr)); align-items: start; }
  .signature-part, .town-sample { display: contents; }

  .hero-window { grid-column: 1 / -1; }
  .hero-national { grid-column: 1 / span 3; }
  .hero-intro { grid-column: 4 / -1; }

  .sources-title, .sources-lead, .sources-pane { grid-column: 1 / -1; }
  .sources-notes { grid-column: 1 / -1; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .postcard-pane { grid-column: 1 / -1; }

  .device-title, .device-pane { grid-column: 1 / -1; }
  .side-stack { grid-column: 3 / -1; }
  .upkeep-window { grid-column: 1 / -1; }
  .upkeep-figures { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }

  .buyers-head, .buyers-lead { grid-column: 1 / -1; }
  .buyers-head { margin-top: var(--storey); }
  .bay { grid-column: 1 / -1; grid-template-columns: repeat(2, minmax(0, 1fr)); margin-bottom: 1.5rem; }
  .bay .light:last-child { grid-column: 1 / -1; }
  .doors-pane { grid-column: 1 / span 2; align-self: stretch; }
  .cooling-pane { grid-column: 3 / -1; }

  .months-head { grid-column: 1 / -1; }
  .months-caption { grid-column: 2 / -1; }
  .months-window { grid-column: 1 / -1; }

  .stair-part { grid-column: 1 / span 3; }
  .costs-part { grid-column: 4 / -1; }
  .costs-pane { align-self: stretch; }

  .faq-panes { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .sample-head, .sample-pane { grid-column: 1 / -1; }
  .covered-pane { grid-column: 1 / span 3; align-self: stretch; }
  .town-trades { grid-column: 4 / -1; }
}

/* ---------- Phones: narrower windows alternate sides of the wall, and the brick stays out from behind text ---------- */
@media (max-width: 767.98px) {
  .on-wall::before { inset: -1.75rem calc(-1 * var(--edge)); }
  .hero-greeting { font-size: clamp(2.75rem, 17vw, 5rem); }
  .stoop span:nth-child(1) { width: calc(100% - 1rem); }
  .stoop span:nth-child(2) { width: calc(100% - 0.5rem); }
  .stoop span:nth-child(3) { width: 100%; }
  .hero-national { width: 88%; justify-self: end; }
  .months-caption { width: 90%; justify-self: end; }
  .covered-pane { width: 92%; justify-self: end; }
  .faq-panes > :nth-child(even) { width: 94%; justify-self: end; }
  .device-steps li { font-size: var(--t-l); }
  .bay { margin-bottom: 1.5rem; }
  .porch-light { display: none; }
  body { --entry-w: calc(100% - 2 * var(--edge)); }
  .stoop::before, .stoop::after { display: none; }


  /* Four columns will not hold at this width: each source becomes a block, the headers its labels. */
  .sources-table {
    display: block;

    & thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
    & tbody, & tr, & th, & td { display: block; }
    & tr { padding-block: 0.85rem; border-bottom: 1px solid var(--line); }
    & tbody tr:first-child { padding-top: 0; }
    & tbody tr:last-child { padding-bottom: 0; border-bottom: 0; }
    & th, & td { padding: 0; border-bottom: 0; }
    & tbody th { font-size: var(--t-body); }
    & td { display: grid; grid-template-columns: 7.75rem minmax(0, 1fr); column-gap: 0.75rem; margin-top: 0.25rem; }
    & td::before { content: attr(data-label); color: var(--fg-muted); font-size: var(--t-xs); line-height: 1.5; white-space: nowrap; }
  }
}

/* ==================== The national guide names no place and shows no market's number (docs/plan-national-pages.md) ====
   The windows the national switch changed: a national figure beside the greeting, the national month chart under a
   twelve-light transom, the cost calculator under the soldier arch, and the made-up sample row with the Coverage pointer
   where the cities and ZIPs were. The pages by place share this stylesheet, so every rule here is scoped to the national
   guide ([data-page="trade"]); the placements above name only classes the national guide uses. */
[data-page="trade"] {
  /* The source line under a national figure: the publisher, linked, and the day it was read. */
  & .national-source {
    margin-top: 0.6rem; font-size: var(--t-xs); line-height: 1.35; color: var(--fg-muted);

    & a { color: var(--fg); text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 0.2em; }
    & .national-read { display: block; }
  }

  /* ---------- Hero: the national figure in the window beside the greeting. With that window wider than the week's
     count was, the greeting window is narrower, so the greeting fits its glass by its longest word ("security." runs
     about 4.2em in this face, so 21.5% of the glass leaves it a margin) instead of running out past the trim. The number
     fits its light the same way (its ten characters run about 5.3em), so it steps down instead of leaving the glass. */
  & .hero-window { container-type: inline-size; }
  & .hero-window .hero-greeting { font-size: min(var(--t-mega), 21.5cqi); }
  & .hero-national-fit { container-type: inline-size; }
  & .hero-national-num {
    font-family: var(--f-head); font-size: min(var(--t-xl), 17.5cqi); font-weight: var(--w-loud); letter-spacing: var(--track-xl);
    line-height: 1; white-space: nowrap; font-variant-numeric: lining-nums proportional-nums;
  }
  & .hero-national-label { font-weight: 650; line-height: 1.3; }

  /* ---------- The national month chart: the source under the heading on the wall, the bars standing on the sill ---------- */
  & .months-head .national-source { margin-top: 0.85rem; font-size: var(--t-s); }
  & .months-window .big-chart .big-col-value { color: var(--fg); font-weight: 650; }
  & .months-window .data-table-toggle { margin-bottom: -0.75rem; }

  /* ---------- Costs: the words and the reader's boxes under the arch, the worked results in the porch window ---------- */
  & .costs-inputs:not([hidden]) {
    display: grid; gap: 1.15rem; margin-top: 1.25rem; padding-top: 1.25rem; border-top: 1px solid var(--line);

    & > p { margin: 0; }
  }
  & .costs-lead .field.calc-field :is(input) { border-color: var(--ink); font-size: var(--t-m); font-weight: 650; font-variant-numeric: tabular-nums; }
  & .calc-entry {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem;

    & input { flex: 0 1 13rem; min-width: 0; }
  }
  & .calc-money { position: relative; display: block; max-width: 13rem; }
  & .costs-lead .field.calc-field .calc-money input { padding-left: 1.85rem; }
  & .calc-unit { position: absolute; left: 0.85rem; top: 50%; translate: 0 -50%; font-size: var(--t-m); font-weight: 650; pointer-events: none; }
  & .calc-help { font-size: var(--t-xs); line-height: 1.4; color: var(--fg-muted); }
  /* Something made up is marked the same way everywhere on the page: the tag in a bordered strip. */
  & .calc-example {
    display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.3rem 0.75rem; border: 2px solid var(--fg);
    font-size: var(--t-xs); font-weight: 750; letter-spacing: 0.04em; line-height: 1.25; text-transform: uppercase;
  }
  & .calc-go { white-space: normal; text-align: left; }
  & .calc-prompt { font-size: var(--t-m); font-weight: 650; line-height: 1.3; }
  /* The demo's cursor reads in ink with a porch edge over the lit glass it crosses. */
  & .costs-part .calc-cursor { --fg: var(--ink); --ground: var(--porch); }

  /* The results take the cost table's look: thin rules, the value at the right, the monthly total loudest. */
  & .costs-results { font-size: var(--t-body); line-height: 1.25; }
  & .calc-row {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, auto); column-gap: 1.5rem; align-items: baseline;
    padding-block: 0.7rem; border-bottom: 1px solid var(--line);

    &:first-child { padding-top: 0; }
    & dt { font-weight: 450; }
    & dd { margin: 0; display: grid; justify-items: end; text-align: right; }
  }
  & .calc-value { font-size: var(--t-m); font-weight: 750; font-variant-numeric: lining-nums tabular-nums; white-space: nowrap; }
  & .calc-total {
    padding-top: 1.25rem; padding-bottom: 0; border-bottom: 0;

    & dt { font-size: var(--t-m); font-weight: var(--w-sub); line-height: 1.2; }
    & .calc-value { font-family: var(--f-head); font-size: var(--t-xl); font-weight: var(--w-loud); letter-spacing: var(--track-xl); line-height: 1; font-variant-numeric: lining-nums proportional-nums; }
  }
  & .calc-how { margin-top: 0.15rem; font-size: var(--t-s); line-height: 1.35; color: var(--fg-muted); font-variant-numeric: tabular-nums; }
  & .calc-echo { color: var(--fg); font-weight: 650; }

  /* ---------- The sample row: the head on the wall, the file in a many-light window, one field to a light ---------- */
  & .sample-head .example-note { margin-top: 0.75rem; font-size: var(--t-m); line-height: 1.35; color: var(--muted-night); max-width: 56ch; }
  & .sample-pane { display: grid; gap: var(--rail); padding: 0; background: var(--ramp-5); }
  & .sample-pane .example-tag {
    --ground: var(--porch);
    display: flex; align-items: center; gap: 0.6rem; margin: 0; padding: calc(var(--pane-pad) * 0.55) var(--pane-pad);
    background: var(--ground); font-size: var(--t-xs); font-weight: 750; letter-spacing: 0.04em; line-height: 1.25; text-transform: uppercase;
  }
  & .example-fields { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--rail); margin: 0; }
  /* Each field: its value in the heading face, then its label and the file's own column name under it. */
  & .example-field {
    display: flex; flex-direction: column-reverse; justify-content: flex-end; gap: 0.3rem;
    padding: 0.85rem var(--pane-pad) 0.95rem; background: var(--ground);

    & dt { display: grid; gap: 0.1rem; }
    & dd {
      margin: 0; font-family: var(--f-head); font-size: var(--t-m); font-weight: var(--w-sub); letter-spacing: -0.015em;
      line-height: 1.2; overflow-wrap: anywhere; font-variant-numeric: lining-nums tabular-nums;
    }
  }
  & .example-label { font-size: var(--t-s); font-weight: 650; line-height: 1.3; }
  & .example-column { font-size: var(--t-xs); color: var(--fg-muted); overflow-wrap: anywhere; }

  /* ---------- The Coverage pointer: a porch window, its link on two rules at the window's foot ---------- */
  & .covered-pane { display: flex; flex-direction: column; }
  & .covered-pane .covered-caption { margin-top: 0.6rem; }
  & .covered-pane-list { margin-top: auto; padding-top: 1.5rem; }
  & .covered-place {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 2.75rem; padding-block: 0.7rem;
    border-top: 2px solid var(--fg); border-bottom: 2px solid var(--fg);
    font-family: var(--f-head); font-size: var(--t-m); font-weight: var(--w-sub); letter-spacing: -0.015em; line-height: 1.2; text-decoration: none;

    & .fa-solid { flex: none; font-size: 0.8em; transition: translate 0.45s var(--roll); }
    &:focus-visible { outline: 2px solid var(--fg); outline-offset: 3px; }
  }
}
@media (hover: hover) {
  [data-page="trade"] a.covered-place:hover .fa-solid { translate: 4px 0; }
}
html.reduced [data-page="trade"] .covered-place .fa-solid { transition: none; }
/* Two fields to a line from a wide phone up, four across the full-width window from lg; a last line that comes up short
   is filled by its last field, so no light stands empty. */
@media (min-width: 576px) {
  [data-page="trade"] .example-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  [data-page="trade"] .example-field:last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@media (min-width: 768px) {
  /* The month chart's own height on its bars; a phone keeps the shared chart's labeled rows (pages.css). */
  [data-page="trade"] .months-window .big-chart { height: clamp(15rem, 38svh, 23rem); }
}
@media (min-width: 992px) {
  [data-page="trade"] .example-fields { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  [data-page="trade"] .example-field:last-child:nth-child(4n + 1) { grid-column: 1 / -1; }
  [data-page="trade"] .example-field:last-child:nth-child(4n + 2) { grid-column: span 3; }
  [data-page="trade"] .example-field:last-child:nth-child(4n + 3) { grid-column: span 2; }
}

/* ==================== Trade pages by place: /for/security/<state>/ ====================
   The same house at dusk: the brick, the cornice, the windows with their trim, lintels, sills and soldier arches, the
   wall type, the week bars, the cost table and the lit entry above all carry over. The state page lays out its own
   front here (trades/local/security-local.njk), with its own class names so the national placements above never reach
   it. Every rule is scoped to those pages, so nothing above changes on the national guide. */
[data-page="trade-local"] {
  /* The greeting fills one wide window and fits it by its longest word (the partial sets who-len-N), so a long place
     or trade steps the size down instead of running out of the glass. 0.6em is a wide letter's share of Montserrat. */
  & .greet-fit { container-type: inline-size; }
  & .hero-greeting { font-size: min(var(--t-mega), calc(100cqi / var(--who-len, 7) / 0.6)); }
  & .who-len-6 { --who-len: 6; } & .who-len-7 { --who-len: 7; } & .who-len-8 { --who-len: 8; } & .who-len-9 { --who-len: 9; }
  & .who-len-10 { --who-len: 10; } & .who-len-11 { --who-len: 11; } & .who-len-12 { --who-len: 12; } & .who-len-13 { --who-len: 13; }
  & .who-len-14 { --who-len: 14; } & .who-len-15 { --who-len: 15; } & .who-len-16 { --who-len: 16; }
  & .greet-window { padding-block: clamp(0.5rem, 0.2rem + 0.7vw, 1rem) var(--pane-pad); }
  & .greet-window .hero-offer { margin-top: clamp(1rem, 0.6rem + 1.2vw, 1.75rem); }
  & .greet-window .hero-title { max-width: 24ch; }

  /* The week's count: the number in the upper light, what it counts in the lower. */
  & .count-window .light + .light { padding-block: 0.7rem; }
  & .intro-light { font-size: var(--t-m); line-height: 1.32; }
  & .residence-moving { font-weight: 650; }

  /* Licensing. The question is the loudest line in its window; the act's answer follows in the window's say size. */
  & .answer-question { font-size: var(--t-l); font-weight: var(--w-head); letter-spacing: var(--track-l); line-height: 1.1; text-wrap: balance; }
  & .answer-window .answer-law { margin-top: 1rem; }
  & .license-wall .wall-note { margin-top: 0.75rem; }
  & .qualify-light { --ground: var(--porch); }
  & .qualify-list { gap: 0.6rem; margin-top: 1rem; }
  & .qualify-list li { font-size: var(--t-m); line-height: 1.25; }

  /* The week: the head on the wall, the line about the buyers in a small porch window, the chart under a transom. */
  & .week-wall .wall-lead { margin-top: 0.75rem; }
  & .chart-window .data-table-toggle { margin-bottom: -0.75rem; }

  /* Costs: the title and its basis on the wall, the table in the window beside them. */
  & .costs-wall .wall-lead { margin-top: 0.75rem; }

  /* Places: the head across the wall, the cities in the big window, the ZIPs as a short ruled list. */
  & .places-wall .wall-lead { margin-top: 0.75rem; }
  & .zips-window {
    & .zips-title { margin: 0 0 0.75rem; color: var(--fg); font-size: var(--t-m); font-weight: var(--w-sub); letter-spacing: -0.01em; line-height: 1.2; }
    & .chip-list { display: grid; gap: 0; }
    & .chip { display: flex; min-height: 3.25rem; padding: 0.4rem 0.5rem; margin-inline: -0.5rem; border: 0; border-bottom: 1px solid var(--line); border-radius: 0; font-size: var(--t-body); }
    & li:last-child .chip { border-bottom: 0; }
    & .chip-count { margin-left: auto; font-size: var(--t-body); }
  }

  /* Links out: a big arrow link to the national guide (and to any city page the registry adds), chips for the other trades. */
  & .links-title { margin-bottom: 0.75rem; }
  & .more-links { border-top: 2px solid var(--fg); }
  & .more-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    min-height: 2.75rem;
    padding-block: 0.7rem;
    border-bottom: 2px solid var(--fg);
    font-family: var(--f-head);
    font-size: var(--t-m);
    font-weight: var(--w-sub);
    letter-spacing: -0.015em;
    line-height: 1.2;
    text-decoration: none;

    & .fa-solid { flex: none; font-size: 0.8em; transition: translate 0.45s var(--roll); }
    &:focus-visible { outline: 2px solid var(--fg); outline-offset: 3px; }
  }
  & .more-links li + li .more-link { border-bottom-width: 1px; border-bottom-color: var(--line); }
  & .links-window .others { margin-top: clamp(1.75rem, 3vw, 2.5rem); }
  & .links-window .chip-list { margin-top: 0.25rem; }
}
@media (hover: hover) {
  [data-page="trade-local"] .more-link:hover .fa-solid { translate: 4px 0; }
}
html.reduced [data-page="trade-local"] .more-link .fa-solid { transition: none; }

/* lg and up: the front on twelve columns. */
@media (min-width: 992px) {
  [data-page="trade-local"] {
    /* The week's count, the page's one showing of it, stays in the first screen beside the greeting; the opening lines
       sit under both in a two-light window. */
    & .greet-window { grid-column: 1 / span 9; }
    & .count-window { grid-column: 10 / -1; }
    & .intro-window { grid-column: 1 / -1; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); }

    /* Licensing: the head and the answer down the left, the double-hung scope window beside them, then who qualifies
       in a tall window under the answer and the agency's two windows stepping down beside it. */
    /* The scope window spans the head's row and the answer's. When it runs taller, the answer's row takes the
       extra (the flexible track), so the answer stays right under the head and the brick shows below it. */
    & .license-front { grid-template-rows: auto minmax(0, 1fr); }
    & .license-wall { grid-column: 1 / span 7; grid-row: 1; }
    & .answer-window { grid-column: 1 / span 7; grid-row: 2; }
    & .scope-window { grid-column: 8 / -1; grid-row: 1 / span 2; align-self: end; }
    & .qualify-window { grid-column: 1 / span 5; grid-row: 3 / span 2; }
    & .agency-window { grid-column: 6 / -1; grid-row: 3; }
    & .staff-window { grid-column: 7 / -1; grid-row: 4; }

    /* The week. */
    & .week-wall { grid-column: 1 / span 8; align-self: center; }
    & .detail-window { grid-column: 9 / -1; align-self: center; }
    & .chart-window { grid-column: 1 / -1; }

    /* Costs: the title and basis on the wall at the left, the table window beside them. */
    & .costs-wall { grid-column: 1 / span 5; align-self: center; }
    & .costs-window { grid-column: 6 / -1; }

    /* Places: the national town front's shape, with the links where the trades were. */
    & .town-local { grid-template-rows: auto 1fr auto; }
    & .local-places { display: contents; }
    & .places-wall { grid-column: 1 / -1; grid-row: 1; }
    & .cities-window { grid-column: 1 / span 8; grid-row: 2 / span 2; align-self: stretch; }
    & .cities-window .city-table { height: 100%; }
    & .zips-window { grid-column: 9 / -1; grid-row: 2; align-self: stretch; }
    & .links-window { grid-column: 9 / -1; grid-row: 3; }
  }
}

/* md: six columns, so the front stays irregular instead of falling into a stack of bands. */
@media (min-width: 768px) and (max-width: 991.98px) {
  [data-page="trade-local"] {
    & .greet-window { grid-column: 1 / -1; }
    & .count-window { grid-column: 1 / span 2; }
    & .intro-window { grid-column: 3 / -1; }

    & .license-wall, & .answer-window { grid-column: 1 / -1; }
    & .scope-window { grid-column: 1 / -1; grid-template-columns: repeat(2, minmax(0, 1fr)); }
    & .qualify-window { grid-column: 1 / span 3; grid-row: span 2; }
    & .agency-window { grid-column: 4 / -1; }
    & .staff-window { grid-column: 4 / -1; }

    & .week-wall { grid-column: 1 / -1; }
    & .detail-window { grid-column: 3 / -1; }
    & .chart-window { grid-column: 1 / -1; }

    & .costs-wall, & .costs-window { grid-column: 1 / -1; }

    & .local-places { display: contents; }
    & .places-wall, & .cities-window { grid-column: 1 / -1; }
    & .zips-window { grid-column: 1 / span 3; align-self: stretch; }
    & .links-window { grid-column: 4 / -1; }
  }
}

/* Phones: one column, the narrower windows alternating sides of the wall as on the national guide. */
@media (max-width: 767.98px) {
  [data-page="trade-local"] {
    & .local-places { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--floor) var(--pier); min-width: 0; }
    & .count-window { width: 74%; justify-self: end; }
    & .scope-window { width: 94%; justify-self: end; }
    & .agency-window { width: 90%; }
    & .staff-window { width: 94%; justify-self: end; }
    & .detail-window { width: 86%; justify-self: end; }
    & .links-window { width: 94%; justify-self: end; }
  }
}
