/* Groundwork — the one stylesheet.
 *
 * Zero dependencies, no build step, no CSS library. Every page emitted by
 * scripts/lib/layout.mjs links this file and nothing else.
 *
 * Base is privacy.html's :root — the real theme (teal/cream, --sand, Playfair Display +
 * DM Sans). The component library below (.hero .card .btn .stat .compare .locknote .badge
 * .pay .signup .wrap) is the one the 148 generated permit pages already use, ported onto
 * those tokens. Tokens were already compatible; --paper/--line take privacy's values.
 *
 * The permit pages still carry their own inline copy of this. That is deliberate for now —
 * they are regenerated by scripts/refresh-permit-pages.mjs and cutting them over is a
 * separate change. Do NOT add a 149th inline copy: new pages go through layout().
 *
 * TWO LAYERS, ON PURPOSE.
 *
 *   1. The LEGACY LAYER (everything down to the "design layer" banner) is what every page
 *      renders with today. It is frozen: the 148 permit pages carry a copy of it and the
 *      current generated pages select on it. Nothing here is renamed or deleted.
 *
 *   2. The DESIGN LAYER (.gw-*) is the 2026-08 redesign, extracted out of its inline styles
 *      into components the generator can emit. Every class is prefixed so it cannot collide
 *      with the legacy names — the redesign wants .bar, .card, .stat and .trade for things
 *      that already mean something else in layer 1 (see the .meter comment below for the
 *      last time that bit us). Pages move over one at a time; both layers ship until the
 *      last page has moved.
 *
 * THE ONE THING THE DESIGN LAYER NEEDS FROM OUTSIDE THIS FILE: DM Mono. Every mono label,
 * count, permit number and eyebrow in layer 2 is set in it, and layout.mjs's FONTS URL does
 * not request it yet. Until `&family=DM+Mono:wght@400;500` is added there, --mono falls
 * through to the platform monospace — legible, correctly sized, wrong face.
 */

:root{
  --ink:#071c26;--deep:#0e3a4a;--deep-2:#0a2a37;--sea:#1f8a8a;--sand:#e3d3ae;
  --paper:#f5f2e9;--body:#22414d;--secondary:#51707c;--muted:#5f7a85;--line:#ddd8c8;
  --card:#fffdf7;--warm:#b45309;--ok:#0f5132;
  --serif:"Playfair Display",Georgia,serif;--sans:"DM Sans",system-ui,sans-serif;

  /* pages.mjs writes `border-left:4px solid var(--teal)` on the quiet free-signup card.
   * --teal was never defined, so the whole declaration was invalid at computed-value time
   * and the card lost its accent edge silently. Aliased rather than renamed in pages.mjs —
   * that file belongs to another change. */
  --teal:var(--sea);

  /* ---------- design layer tokens (2026-08 redesign) ----------
   * Same brand as above — paper, deep, sea, sand, Playfair + DM Sans — with the darker
   * grounds, the warm band and the mono greys the redesign added. Named so nothing here
   * overwrites a token the legacy layer or the 148 permit pages read. */

  /* grounds, lightest to darkest */
  --paper-2:#ede9dc;      /* the warm band that alternates against --paper between sections */
  --night:#08222c;        /* darkest ground: topbar, stat row, footer, sticky bar */

  /* ink on paper */
  --text:#0a2b37;         /* headings and hard facts */
  --text-2:#4c5f66;       /* prose */
  --text-3:#5f7178;       /* mono labels, table headers */
  --text-4:#8d9aa0;       /* fine print and footnotes */
  --text-5:#93a0a5;       /* placeholders, list index numbers, rule marks */

  /* teal family — one hue, four jobs */
  --mint:#7fd0cf;         /* teal legible on a dark ground: eyebrows, the italic clause */
  --sea-2:#25a3a3;        /* button hover */
  --sea-ink:#166f6f;      /* teal TEXT on a teal-tinted chip; --sea fails contrast there */
  --pulse:#2ec5b6;        /* the live dot in the hero eyebrow */

  /* hairlines. The redesign rules everything with translucent ink, not --line, so the
   * rules sit on whatever ground the section uses instead of fighting it. */
  --hair:rgba(14,58,74,.09);      /* row rule inside a table or a lead card */
  --hair-2:rgba(14,58,74,.14);    /* component border */
  --hair-3:rgba(14,58,74,.16);    /* header rule, the heavier of the two */
  --edge:rgba(227,211,174,.16);   /* the same idea in sand, for dark grounds */

  /* geometry. 2px is the redesign's signature: square enough to read as a document,
   * round enough not to look unstyled. The legacy layer's 10–16px radii stay put. */
  --r:2px;
  --r-raise:3px;          /* cards that float off the page (inbox preview) */

  /* elevation. All four are long, soft and biased downward — a document lifted off a
   * table, never a material-design drop shadow. */
  --sh-raise:0 40px 80px -30px rgba(4,20,27,.75);
  --sh-panel:0 30px 60px -34px rgba(4,20,27,.8);
  --sh-card:0 24px 50px -34px rgba(10,43,55,.5);
  --sh-col:0 20px 44px -34px rgba(10,43,55,.45);

  /* section rhythm. --gutter and --shell are what make every band line up: the full-bleed
   * coloured section pays the gutter, the 1180px shell inside it does not. */
  --shell:1180px;
  --gutter:clamp(18px,5vw,44px);
  --section:clamp(58px,9vw,104px);
  --section-2:clamp(52px,8vw,92px);   /* the quieter sections between the loud ones */
  --section-3:clamp(34px,4.5vw,48px); /* strips: stat row, trust bar */
  --pad-card:clamp(24px,3vw,34px);
  --pad-tile:clamp(22px,2.6vw,30px);

  /* type scale */
  --t-display:clamp(38px,7.2vw,66px); /* homepage h1 only */
  --t-h1:clamp(34px,6vw,58px);        /* every other page's h1 */
  --t-h2:clamp(28px,4.4vw,44px);
  --t-h2-sm:clamp(26px,3.6vw,38px);   /* h2 in a section that is not the section's point */
  --t-h3:clamp(19px,2.2vw,23px);
  --t-lede:clamp(15.5px,1.6vw,18px);
  --t-body:15px;
  --t-label:11px;                     /* mono eyebrows */
  --t-fine:12.5px;

  --mono:"DM Mono",ui-monospace,SFMono-Regular,Menlo,monospace;

  /* GROUND CONTEXT. Components read these, not the raw colours, so one .gw-lede, .gw-step
   * or .gw-btn.ghost works on paper and on the deep ground without a second rule per
   * component. The default below is paper; the dark grounds swap them, and a cream card
   * sitting inside a dark section swaps them back (see "light islands").
   *
   * These eleven are declared in three places and must stay in step. Miss one on a dark
   * ground and the thing it colours goes ink-on-ink — invisible, and invisible in a way a
   * test cannot see. */
  --gw-ground:var(--paper);       /* the ground a nested tile paints itself */
  --gw-head:var(--text);
  --gw-text:var(--text-2);
  --gw-dim:var(--text-3);
  --gw-fine:var(--text-4);
  --gw-accent:var(--sea);
  --gw-rule:rgba(14,58,74,.25);   /* the short rule in an eyebrow */
  --gw-hair:var(--hair-2);        /* component border */
  --gw-line:rgba(14,58,74,.28);   /* outline border, resting */
  --gw-line-2:rgba(14,58,74,.4);  /* outline border, when the outline IS the statement */
  --gw-line-hi:var(--sea);        /* outline border, hover */
  --gw-tint:rgba(31,138,138,.08); /* the wash under a hovered outline */
  --gw-mark-bg:rgba(31,138,138,.1);   /* .gw-mark — a measured figure, tinted */
  --gw-mark-line:rgba(31,138,138,.5); /* .gw-mark — and dash-underlined */
}

*{box-sizing:border-box}
body{margin:0;background:var(--paper);color:var(--body);font-family:var(--sans);font-size:16.5px;line-height:1.7;-webkit-font-smoothing:antialiased}
a{color:var(--sea);text-decoration:underline;text-underline-offset:2px}
img{max-width:100%;height:auto}
hr{border:0;border-top:1px solid var(--line);margin:40px 0}

/* ---------- shell ---------- */
.wrap{max-width:900px;margin:0 auto;padding:0 28px}
.wrap.narrow{max-width:760px}
.topbar{background:var(--ink);color:#a9c4c6;font-size:13px}
.topbar .wrap{display:flex;justify-content:space-between;align-items:center;gap:12px;height:40px}
.topbar a{color:#fff;text-decoration:none;font-weight:600}
.site-header{background:var(--paper);border-bottom:1px solid var(--line)}
.site-header .wrap{display:flex;align-items:center;justify-content:space-between;gap:18px;min-height:76px;flex-wrap:wrap}
.brand{display:flex;align-items:center;gap:12px;text-decoration:none}
.brand .badge{width:40px;height:40px;border-radius:50%;background:var(--deep);display:grid;place-items:center;border:2px solid var(--sand);margin:0;padding:0;letter-spacing:0;text-transform:none;font-size:inherit}
.brand .badge span{font-family:var(--serif);font-weight:700;color:#fff;font-size:19px;line-height:1}
.brand .name{font-family:var(--serif);font-weight:700;font-size:21px;color:var(--deep)}
.brand .name em{font-style:italic;font-weight:500;color:var(--sea)}
.site-nav{display:flex;align-items:center;gap:18px;flex-wrap:wrap}
.site-nav a{font-size:14.5px;font-weight:600;color:var(--deep);text-decoration:none}
.site-nav a:hover{color:var(--sea)}
.site-nav a[aria-current="page"]{color:var(--sea);text-decoration:underline;text-underline-offset:5px}
.back{font-size:14.5px;font-weight:600;color:var(--deep);text-decoration:none}
.back:hover{color:var(--sea)}
main{padding:44px 0 88px}
footer{background:var(--ink);color:#7d9a9c;font-size:13.5px;padding:28px 0}
footer .wrap{display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap}
footer a{color:#a9c2c3;text-decoration:underline;text-underline-offset:3px}
footer b{color:var(--sand)}

/* ---------- type ---------- */
h1{font-family:var(--serif);font-size:clamp(32px,5vw,48px);color:var(--deep);letter-spacing:-.6px;line-height:1.12;margin:0 0 12px}
h1 em{font-style:italic;color:var(--sea);font-weight:500}
h2{font-family:var(--serif);font-size:26px;color:var(--deep);margin:44px 0 12px;letter-spacing:-.2px;line-height:1.25}
h3{font-family:var(--sans);font-size:17px;color:var(--deep);margin:0 0 8px}
p,li{color:var(--body)}
ul{padding-left:22px}
ul.clean{padding-left:20px}
ul.clean li{margin:6px 0}
.k{font-size:12px;letter-spacing:.16em;text-transform:uppercase;font-weight:700;color:var(--sea)}
.lede{font-size:19px;line-height:1.6;color:var(--secondary)}
.note{font-size:13.5px;color:var(--muted)}
.fine{font-size:12.5px;color:var(--muted);margin-top:10px}
.updated{font-size:13px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin-bottom:36px}
.person{color:var(--warm);font-weight:700}
.foot{font-size:12.5px;color:var(--muted);margin-top:28px;line-height:1.55}

/* ---------- hero ---------- */
.hero{background:linear-gradient(160deg,#14495c,var(--deep) 55%,var(--deep-2));color:#fff;border-radius:16px;padding:34px 30px;margin:0 0 22px}
.hero .k{color:#8fd6d0}
.hero h1{color:#fff;margin:10px 0 12px}
.hero h1 em{color:var(--sand)}
.hero p{margin:0 0 6px;color:#cfe1e1;font-size:18px;line-height:1.6}
.hero p b{color:#fff}
.hero .btn{margin-top:18px}
.hero-split{display:grid;grid-template-columns:1fr;gap:22px}

/* ---------- cards, callouts ---------- */
.card{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:20px 22px;margin:16px 0}
.card h2{margin:0 0 10px;font-size:21px}
.card h3{margin:0 0 8px}
.callout{background:var(--card);border:1px solid var(--line);border-left:4px solid var(--sea);border-radius:12px;padding:20px 22px;margin:18px 0}
.callout h3{font-family:var(--sans);font-size:13px;letter-spacing:.16em;text-transform:uppercase;color:var(--sea);margin:0 0 10px}
.locknote{background:#efece2;border-left:4px solid var(--sea);padding:12px 14px;margin:12px 0;font-size:14.5px;color:var(--secondary);border-radius:0 8px 8px 0}
.locknote b{color:var(--deep)}
.meta{font-size:14.5px;color:var(--muted)}
.meta b{color:var(--deep)}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:16px 0}
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin:16px 0}
@media(max-width:700px){.grid2,.grid3{grid-template-columns:1fr}}

/* ---------- buttons ---------- */
button,.btn{display:inline-block;margin-top:14px;background:var(--sea);color:#fff!important;text-decoration:none;border:0;border-radius:10px;padding:13px 20px;font-family:var(--sans);font-weight:700;font-size:15.5px;cursor:pointer;line-height:1.2}
.btn:hover{background:#1a7676}
.btn.ghost{background:transparent;color:var(--deep)!important;border:2px solid var(--deep)}
.btn.ghost:hover{background:rgba(14,58,74,.06)}
.hero .btn.ghost{color:#fff!important;border-color:rgba(255,255,255,.6)}
.btn.small{margin-top:0;padding:9px 13px;font-size:13.5px}
.btn.block{display:block;text-align:center}

/* ---------- stats ---------- */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin:18px 0}
.stat{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:14px 16px}
.stat b{display:block;font-family:var(--serif);font-size:30px;line-height:1.1;color:var(--deep)}
.stat span{display:block;font-size:12.5px;color:var(--muted);margin-top:4px;line-height:1.4}

/* ---------- badges ---------- */
.badge{display:inline-block;font-size:11px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;background:#e7f0f0;color:var(--deep);padding:4px 9px;border-radius:999px;margin-bottom:8px;white-space:nowrap}
.badge.paid{background:var(--deep);color:#fff}
.badge.a{background:var(--deep);color:#fff}
.badge.b{background:var(--sand);color:#4a3a17}
.badge.off{background:#e8e4d7;color:var(--muted)}

/* ---------- compare ---------- */
.compare{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:18px 0}
@media(max-width:640px){.compare{grid-template-columns:1fr}}
.compare .box{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:18px 20px}
.compare .box.us{border-color:var(--sea);box-shadow:0 0 0 1px var(--sea)}
.compare h3{margin:0 0 10px;font-size:17px;color:var(--deep)}
.compare .box.us h3{color:var(--sea)}

/* ---------- tables ---------- */
table{width:100%;border-collapse:collapse;margin:16px 0;font-size:15px;background:var(--card);border:1px solid var(--line);border-radius:12px;overflow:hidden}
th,td{text-align:left;padding:11px 13px;border-bottom:1px solid var(--line);vertical-align:top}
th{font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);font-weight:700;background:#efece2}
tr:last-child td{border-bottom:0}
td.n,th.n{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}

/* ---------- pay / signup ---------- */
.pay,.signup{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:22px 24px;margin:22px 0}
.pay-k,.signup-k{font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--sea);font-weight:700;margin-bottom:10px}
.pay .price{font-family:var(--serif);font-size:34px;color:var(--deep);line-height:1.1;margin:0 0 4px}
label{display:block;font-size:13px;font-weight:700;margin:14px 0 6px;color:var(--deep)}
input,select{width:100%;padding:12px;border:1px solid var(--line);border-radius:10px;font-size:16px;font-family:var(--sans);background:#fff;color:var(--body)}
.msg{font-size:14px;color:#2b8a6f;font-weight:700;margin-top:10px}
.owner{display:grid;grid-template-columns:150px 1fr;gap:20px;align-items:start}
@media(max-width:600px){.owner{grid-template-columns:1fr}}
.owner img{border-radius:12px;border:1px solid var(--line)}

/* ---------- small screens ---------- */
@media(max-width:560px){
  body{font-size:16px}
  .wrap{padding:0 20px}
  .topbar{font-size:12px}
  .topbar .wrap{height:auto;padding-top:7px;padding-bottom:7px;gap:10px}
  .site-header .wrap{min-height:0;padding-top:14px;padding-bottom:14px;gap:10px}
  .site-nav{gap:14px}
  .site-nav a{font-size:14px}
  .hero{padding:26px 20px;border-radius:14px}
  .hero p{font-size:16.5px}
  .card,.callout,.pay,.signup{padding:16px 18px}
  main{padding:28px 0 64px}
  footer .wrap{flex-direction:column;gap:8px}
}

/* ---------- hero grid + digest preview (the product, visible) ---------- */
.hero-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:30px;align-items:center}
@media(max-width:820px){.hero-grid{grid-template-columns:1fr}}
.trust-row{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px}
.chip{font-size:12.5px;font-weight:700;color:#dcebe9;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.22);border-radius:999px;padding:5px 11px;white-space:nowrap}
.preview{background:var(--card);border-radius:14px;box-shadow:0 18px 50px rgba(4,26,35,.45);overflow:hidden;color:var(--body);font-size:14px}
.preview .bar{display:flex;align-items:center;gap:6px;background:#eae6d9;padding:9px 12px;border-bottom:1px solid var(--line)}
.preview .bar i{width:10px;height:10px;border-radius:50%;background:#d6cfba;display:inline-block}
.preview .bar span{margin-left:6px;font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.preview .subject{padding:12px 16px;border-bottom:1px solid var(--line)}
.preview .subject b{display:block;color:var(--deep);font-size:15px}
.preview .subject span{font-size:12px;color:var(--muted)}
.lead-card{padding:13px 16px;border-bottom:1px solid var(--line)}
.lead-card .trade{display:inline-block;font-size:10.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;background:#e7f0f0;color:var(--deep);border-radius:999px;padding:3px 8px;margin-bottom:6px}
.lead-card .addr{font-family:var(--serif);font-weight:700;color:var(--deep);font-size:16.5px}
.lead-card .scope{font-size:13px;color:var(--secondary);margin:2px 0 6px}
.lead-card .meta{font-size:12px;color:var(--muted)}
.lead-card .meta b{color:var(--deep)}
.lead-card .phone{color:var(--ok);font-weight:700}
.preview .more{padding:11px 16px;font-size:12.5px;color:var(--muted);text-align:center;background:#faf7ee}

/* ---------- feature tiles ---------- */
.tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:16px 0}
@media(max-width:820px){.tiles{grid-template-columns:1fr 1fr}}
@media(max-width:420px){.tiles{grid-template-columns:1fr}}
.tile{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:14px 15px}
.tile b{display:block;color:var(--deep);margin-bottom:4px;font-size:14.5px}
.tile span{font-size:13px;color:var(--secondary);line-height:1.5}

/* ---------- promoted signup ---------- */
.signup-hero{background:var(--card);border:2px solid var(--sea);border-radius:16px;padding:24px 26px;margin:22px 0;box-shadow:0 10px 34px rgba(31,138,138,.12)}
.signup-hero h2{margin:0 0 6px}
.signup-hero form{display:grid;grid-template-columns:1fr 1.4fr auto;gap:12px;align-items:end;margin-top:14px}
@media(max-width:700px){.signup-hero form{grid-template-columns:1fr}}
.signup-hero form label{margin:0}
.signup-hero form button{margin-top:0;white-space:nowrap}

/* ---------- footer columns ---------- */
footer .cols{display:grid;grid-template-columns:2fr 1fr 1fr;gap:24px;margin-bottom:18px}
@media(max-width:640px){footer .cols{grid-template-columns:1fr}}
footer .cols h4{color:#fff;font-size:12.5px;margin:0 0 8px;letter-spacing:.08em;text-transform:uppercase}
footer .cols a{display:block;margin:5px 0;text-decoration:none}
footer .cols a:hover{text-decoration:underline}
footer .cols p{margin:0;line-height:1.6;color:#a9c2c3}
footer .legal{border-top:1px solid rgba(255,255,255,.12);padding-top:14px;display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap}

/* ---------- meters (/stats) ----------
 * CSS-only bars: the width is computed by the generator from the same count the cell prints,
 * so the picture cannot disagree with the number. Named .meter, not .bar — .bar already means
 * the fake window chrome inside .preview on the homepage. */
.meter{position:relative;height:13px;min-width:90px;background:#eae6d9;border-radius:7px;overflow:hidden}
.meter i{position:absolute;top:0;left:0;bottom:0;background:var(--sea);border-radius:7px}

/* ---------- misc ---------- */
.crumb{font-size:13.5px;color:var(--muted);margin-bottom:14px}
.crumb a{color:var(--muted)}
.faq{margin:16px 0}
.faq h3{margin:22px 0 6px;font-size:17px}
.tick{color:var(--sea);font-weight:800}
.cross{color:#a4595c;font-weight:800}


/* ============================================================================
 * DESIGN LAYER — the 2026-08 redesign, as components.
 *
 * Everything below is prefixed .gw-. Nothing above this line is touched by it, so a page
 * can be on the old components, the new ones, or halfway through. Placement matters: this
 * layer comes last, so where a bare element rule from layer 1 (button, input, table, h1)
 * would otherwise leak into a new component, the scoped .gw- rule outranks it.
 * ========================================================================= */

/* ---------- grounds ----------
 * A full-bleed band of colour with the shell centred inside it. Sections alternate
 * paper → band → deep → night; that alternation IS the page's structure, which is why the
 * ground classes also swap the context tokens rather than each component carrying two
 * colour rules. Drop the token swap and every eyebrow, rule and lede on a dark section
 * renders in its paper colours and disappears. */
.gw-paper{background:var(--paper);--gw-ground:var(--card)}
.gw-band{background:var(--paper-2);--gw-ground:var(--paper)}
.gw-dark{background:var(--deep)}
.gw-night{background:var(--night)}
/* Every dark ground on the site, including the two that also carry a photograph. The hero
 * and the region markers are listed here rather than given .gw-dark because they paint
 * their own background; what they need is the token swap, not the flat fill. */
.gw-dark,.gw-night,.gw-hero,.gw-marker,.gw-stickybar{
  --gw-ground:var(--deep);
  --gw-head:#fffdf7;
  --gw-text:rgba(245,242,233,.75);
  --gw-dim:rgba(245,242,233,.55);
  --gw-fine:rgba(245,242,233,.5);
  --gw-accent:var(--mint);
  --gw-rule:rgba(227,211,174,.3);
  --gw-hair:var(--edge);
  --gw-line:rgba(227,211,174,.42);
  --gw-line-2:rgba(227,211,174,.42);
  --gw-line-hi:var(--sand);
  --gw-tint:rgba(227,211,174,.08);
  --gw-mark-bg:rgba(127,208,207,.12);
  --gw-mark-line:rgba(127,208,207,.5);
}
.gw-dark,.gw-night{color:var(--gw-text)}
.gw-night{--gw-ground:var(--night)}
/* LIGHT ISLANDS. A cream card inside a dark section is back on paper, so it takes the paper
 * tokens again. Without this the inbox preview's teal accents and hairlines inherit the
 * hero's cream-on-dark values and vanish against their own background. */
.gw-inbox .frame,.gw-signup,.gw-card,.gw-col,.gw-table{
  --gw-ground:var(--card);
  --gw-head:var(--text);
  --gw-text:var(--text-2);
  --gw-dim:var(--text-3);
  --gw-fine:var(--text-4);
  --gw-accent:var(--sea);
  --gw-rule:rgba(14,58,74,.25);
  --gw-hair:var(--hair-2);
  --gw-line:rgba(14,58,74,.28);
  --gw-line-2:rgba(14,58,74,.4);
  --gw-line-hi:var(--sea);
  --gw-tint:rgba(31,138,138,.08);
  --gw-mark-bg:rgba(31,138,138,.1);
  --gw-mark-line:rgba(31,138,138,.5);
  color:var(--gw-text);
}
/* Hairline seams between adjacent bands. Without them two light grounds meeting at a
 * section boundary read as one very tall section. */
.gw-band+.gw-band,.gw-band.ruled,.gw-paper.ruled{border-top:1px solid rgba(14,58,74,.1)}
.gw-night.ruled,.gw-dark.ruled{border-top:1px solid rgba(227,211,174,.12)}

/* ---------- shell ---------- */
.gw-section{padding:var(--section) var(--gutter);text-wrap:pretty}
.gw-section.quiet{padding:var(--section-2) var(--gutter)}
.gw-section.strip{padding:var(--section-3) var(--gutter)}
.gw-shell{max-width:var(--shell);margin:0 auto}
/* Two columns that fold themselves: auto-fit + minmax is what makes the hero, the signup
 * split and the compare columns collapse at their own natural width instead of at a
 * breakpoint we guessed. */
.gw-split{display:grid;grid-template-columns:repeat(auto-fit,minmax(340px,1fr));gap:clamp(38px,5vw,64px);align-items:center}
.gw-split.top{align-items:start}
.gw-split.narrow{grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:clamp(32px,5vw,64px)}
/* Anything with an id is a scroll target under a sticky header; without the margin the
 * header covers the heading you just jumped to. */
[id]{scroll-margin-top:96px}

/* ---------- type ---------- */
.gw-display,.gw-h1,.gw-h2,.gw-h3{font-family:var(--serif);font-weight:600;color:var(--gw-head);letter-spacing:-.02em;margin:0}
.gw-display{font-size:var(--t-display);line-height:1.04;letter-spacing:-.022em;margin-bottom:22px}
.gw-h1{font-size:var(--t-h1);line-height:1.06;letter-spacing:-.022em;margin-bottom:18px}
.gw-h2{font-size:var(--t-h2);line-height:1.1;margin-bottom:18px}
.gw-h2.sm{font-size:var(--t-h2-sm);line-height:1.14}
.gw-h3{font-size:var(--t-h3);line-height:1.25;letter-spacing:-.01em;margin-bottom:9px}
/* The second clause, in italic teal. It is the one flourish the design allows itself and
 * it carries the argument — the headline states the fact, the italic states the catch. */
.gw-display em,.gw-h1 em,.gw-h2 em,.gw-h3 em{font-style:italic;font-weight:500;color:var(--gw-accent)}
.gw-lede{font-size:var(--t-lede);line-height:1.62;color:var(--gw-text);margin:0 0 22px;max-width:52ch}
.gw-lede.wide{max-width:62ch}
.gw-copy{font-size:15.5px;line-height:1.65;color:var(--gw-text);margin:0 0 16px;max-width:56ch}
.gw-fine{font-size:var(--t-fine);line-height:1.6;color:var(--gw-fine);margin:18px 0 0;max-width:72ch}
/* Headlines want a short measure or they turn into paragraphs. */
.gw-clamp{max-width:22ch}
.gw-clamp.tight{max-width:18ch}
.gw-clamp.loose{max-width:24ch}

/* ---------- eyebrows ----------
 * .gw-eyebrow is the hero's: live dot, mono label, rule, timestamp.
 * .gw-step is the numbered section marker (01 / TRY IT FREE) that gives the page its spine. */
.gw-eyebrow,.gw-step{display:flex;align-items:center;gap:11px;flex-wrap:wrap;font-family:var(--mono);font-size:var(--t-label);letter-spacing:.14em;text-transform:uppercase;color:var(--gw-accent);margin:0 0 20px}
.gw-eyebrow .dot{width:7px;height:7px;border-radius:50%;background:var(--pulse);flex:0 0 auto}
.gw-eyebrow .rule,.gw-step .rule{height:1px;background:var(--gw-rule);flex:0 0 auto}
.gw-eyebrow .rule{width:18px}
.gw-step{gap:13px;letter-spacing:.16em}
.gw-step .rule{width:28px}
.gw-step .label{color:var(--gw-dim)}
/* The trailing "Updated <date>" — a live value from stats.json, deliberately quieter than
 * the label it follows. */
.gw-eyebrow .dim{color:var(--gw-dim);letter-spacing:.1em}
/* A live number, marked as live: tinted, dashed-underlined, and never styled by hand in a
 * template. Every count the generator substitutes wears this so a reader can tell measured
 * figures from prose at a glance. */
.gw-mark{background:var(--gw-mark-bg);border-bottom:1px dashed var(--gw-mark-line);padding:1px 4px;color:var(--gw-head)}

/* ---------- buttons and outline links ---------- */
.gw-btn{display:inline-flex;align-items:center;gap:10px;margin:0;background:var(--sea);color:#fffdf7;text-decoration:none;font-family:var(--sans);font-size:var(--t-body);font-weight:700;line-height:1.2;padding:15px 24px;border:0;border-radius:var(--r);cursor:pointer;transition:background .2s ease,transform .2s ease,border-color .2s ease}
.gw-btn:hover{background:var(--sea-2);color:#fffdf7;transform:translateY(-1px)}
.gw-btn .arrow{font-family:var(--mono);opacity:.7}
/* Ink primary: used where teal would collide with a teal-topped card behind it. */
.gw-btn.ink{background:var(--deep)}
.gw-btn.ink:hover{background:var(--sea)}
/* Secondary is an outline, never a second filled button — two filled buttons and neither
 * is the primary action. */
.gw-btn.ghost{background:transparent;border:1px solid var(--gw-line);color:var(--gw-head);font-weight:500}
.gw-btn.ghost:hover{background:var(--gw-tint);border-color:var(--gw-line-hi);color:var(--gw-head);transform:none}
.gw-btn.sm{font-size:13px;padding:10px 16px}
.gw-btn.block{width:100%;justify-content:center}
.gw-btns{display:flex;gap:12px;flex-wrap:wrap;margin:0 0 30px}
/* The mono outline link — "City open data →", "$39/mo · 12/wk", the trust-bar pair. Reads
 * as a reference, not a sale, which is the whole point of where it is used. */
.gw-outline{display:inline-block;font-family:var(--mono);font-size:var(--t-fine);color:var(--gw-head);background:transparent;border:1px solid var(--gw-line);border-radius:var(--r);padding:11px 15px;text-decoration:none;white-space:nowrap;transition:background .2s ease,border-color .2s ease,color .2s ease}
.gw-outline:hover{border-color:var(--gw-line-hi);background:var(--gw-tint);color:var(--gw-head)}
.gw-outline.sm{font-size:12px;padding:7px 11px}
.gw-outline.sm:hover{background:var(--sea);border-color:var(--sea);color:#fffdf7}
.gw-outline.solid{background:var(--deep);border-color:var(--deep);color:#fffdf7;padding:8px 12px;font-size:12px}
.gw-outline.solid:hover{background:var(--sea);border-color:var(--sea)}
/* A link that is an underline and nothing else. */
.gw-link{font-family:var(--mono);font-size:13px;letter-spacing:.06em;text-transform:uppercase;color:var(--gw-head);text-decoration:none;border-bottom:1px solid var(--sea);padding-bottom:3px}
.gw-link:hover{color:var(--sea)}
/* Tel/permit numbers in running prose. */
.gw-num{font-family:var(--mono);color:inherit;text-decoration-color:rgba(227,211,174,.5)}

/* ---------- tags ----------
 * Tier A vs Tier B, everywhere they appear. Solid teal = owner-pulled, outline = all new
 * permits. They must not look interchangeable: which one a jurisdiction gets is the whole
 * honesty argument of the coverage page. */
.gw-tag{display:inline-block;font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;background:var(--sea);color:#fffdf7;padding:5px 10px;border-radius:var(--r);white-space:nowrap}
.gw-tag.outline{background:transparent;border:1px solid var(--gw-line-2);color:var(--gw-head);padding:4px 9px}
.gw-tag.off{background:transparent;border:1px solid var(--gw-line);color:var(--gw-dim);padding:3px 7px;text-transform:none;letter-spacing:.04em}

/* ---------- topbar ---------- */
.gw-topbar{background:var(--night);color:rgba(245,242,233,.66);font-family:var(--mono);font-size:11px;letter-spacing:.08em}
.gw-topbar .inner{max-width:var(--shell);margin:0 auto;padding:8px var(--gutter);display:flex;justify-content:space-between;align-items:center;gap:16px}
.gw-topbar a{color:var(--sand);text-decoration:none;white-space:nowrap}
.gw-topbar a:hover{color:#fffdf7}

/* ---------- site header ----------
 * Sticky and dark from the first pixel, so the header never has to cross from transparent
 * to solid over a photo. [data-stuck] is the compact scrolled state; a page with no script
 * simply never gets it and stays in the tall state, which is correct, not broken. */
.gw-header{position:sticky;top:0;z-index:60;background:var(--deep);border-bottom:1px solid rgba(227,211,174,0);padding:15px var(--gutter);transition:background .35s ease,padding .35s ease,border-color .35s ease}
.gw-header[data-stuck]{background:rgba(9,37,48,.94);backdrop-filter:saturate(1.3) blur(12px);-webkit-backdrop-filter:saturate(1.3) blur(12px);border-bottom-color:rgba(227,211,174,.18);padding-top:9px;padding-bottom:9px}
.gw-header .inner{max-width:var(--shell);margin:0 auto;display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap}
.gw-header .right{display:flex;align-items:center;gap:clamp(14px,2.4vw,28px);flex-wrap:wrap}
.gw-brand{display:flex;align-items:center;gap:11px;text-decoration:none}
.gw-brand .mark{width:34px;height:34px;flex:0 0 auto;border-radius:50%;background:var(--deep);border:2px solid var(--sand);display:flex;align-items:center;justify-content:center;font-family:var(--serif);font-weight:700;font-size:19px;color:#fffdf7}
.gw-brand .name{font-family:var(--serif);font-size:23px;font-weight:600;color:var(--paper);letter-spacing:-.01em}
.gw-brand .name em{font-style:normal;color:var(--mint);font-weight:500}
.gw-nav{display:flex;gap:clamp(14px,2.2vw,26px);flex-wrap:wrap;font-family:var(--mono);font-size:12px;letter-spacing:.06em;text-transform:uppercase}
.gw-nav a{color:rgba(245,242,233,.78);text-decoration:none}
.gw-nav a:hover{color:#fffdf7}
.gw-nav a[aria-current="page"]{color:var(--mint)}

/* ---------- hero ----------
 * Photo pinned to the bottom, masked out at the top so it fades into the flat deep ground
 * rather than ending on a hard edge; two scrims over it — one vertical to seat the proof
 * strip, one horizontal to hold the headline. Both scrims are pseudo-elements so the
 * generator emits one photo div and nothing else. Remove either and the cream type over
 * the sunset half of the skyline drops below contrast. */
.gw-hero{position:relative;overflow:hidden;background:var(--deep);padding:clamp(46px,7vw,84px) var(--gutter) clamp(64px,9vw,110px)}
.gw-hero .photo{position:absolute;left:0;right:0;bottom:0;height:min(62%,560px);z-index:0;pointer-events:none;-webkit-mask-image:linear-gradient(180deg,rgba(0,0,0,0) 0%,rgba(0,0,0,.55) 14%,#000 34%,#000 100%);mask-image:linear-gradient(180deg,rgba(0,0,0,0) 0%,rgba(0,0,0,.55) 14%,#000 34%,#000 100%)}
.gw-hero .photo img{width:100%;height:100%;object-fit:cover;object-position:50% 40%;display:block}
.gw-hero::before,.gw-hero::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none}
.gw-hero::before{background:linear-gradient(180deg,rgba(14,58,74,.5) 0%,rgba(14,58,74,.42) 42%,rgba(8,34,44,.86) 100%)}
.gw-hero::after{background:linear-gradient(90deg,rgba(8,34,44,.9) 0%,rgba(8,34,44,.68) 34%,rgba(8,34,44,.2) 68%,rgba(8,34,44,.05) 100%)}
.gw-hero .gw-shell{position:relative;z-index:2}
.gw-hero .gw-display{color:#fffdf7}
/* "Or call (760)… — that is Chad, and he picks up." Sits between the buttons and the proof
 * strip because the phone number IS the third call to action. */
.gw-hero .callline{font-size:14.5px;line-height:1.5;color:rgba(245,242,233,.7);margin:0 0 26px}
.gw-hero .callline a{color:#fffdf7}
/* The slash-separated proof strip that closes the hero. Mono, small caps, dim: three facts
 * a contractor can check, deliberately not styled as badges. */
.gw-proof{display:flex;gap:9px 22px;flex-wrap:wrap;font-family:var(--mono);font-size:11.5px;letter-spacing:.05em;text-transform:uppercase;color:rgba(245,242,233,.58);margin:0}
.gw-proof .sep{color:rgba(227,211,174,.3)}
/* The surveyor's contour overlay. Blend mode is what keeps it a texture instead of a
 * drawing sitting on top of the photograph. */
.gw-contours{position:absolute;inset:-8% -10% 0 -10%;z-index:1;pointer-events:none;mix-blend-mode:soft-light}
.gw-contours svg{width:100%;height:100%}
.gw-contours.plain{mix-blend-mode:normal;inset:-20% -5% 0 40%;z-index:0}

/* ---------- corner ticks ----------
 * The four survey brackets around the inbox preview and the signup card. Eight background
 * layers on one pseudo-element rather than four positioned divs, so the generator emits one
 * wrapper: the card gets its frame without the template carrying decoration. */
.gw-ticks{position:relative}
.gw-ticks::before{content:"";position:absolute;inset:-9px;z-index:3;pointer-events:none;--c:rgba(227,211,174,.5);
  background:
    linear-gradient(var(--c),var(--c)) 0 0/20px 1px no-repeat,
    linear-gradient(var(--c),var(--c)) 0 0/1px 20px no-repeat,
    linear-gradient(var(--c),var(--c)) 100% 0/20px 1px no-repeat,
    linear-gradient(var(--c),var(--c)) 100% 0/1px 20px no-repeat,
    linear-gradient(var(--c),var(--c)) 0 100%/20px 1px no-repeat,
    linear-gradient(var(--c),var(--c)) 0 100%/1px 20px no-repeat,
    linear-gradient(var(--c),var(--c)) 100% 100%/20px 1px no-repeat,
    linear-gradient(var(--c),var(--c)) 100% 100%/1px 20px no-repeat}
/* Two corners only — the quieter version used on cards that sit on paper. */
.gw-ticks.diag::before{inset:-8px;
  background:
    linear-gradient(var(--c),var(--c)) 0 0/18px 1px no-repeat,
    linear-gradient(var(--c),var(--c)) 0 0/1px 18px no-repeat,
    linear-gradient(var(--c),var(--c)) 100% 100%/18px 1px no-repeat,
    linear-gradient(var(--c),var(--c)) 100% 100%/1px 18px no-repeat}
.gw-ticks.teal::before{--c:rgba(31,138,138,.5)}

/* ---------- the inbox preview ----------
 * The product, rendered. Every other block on the page describes the Monday email; this one
 * is the Monday email, which is why it earns the deepest shadow on the site and the only
 * 3px radius. Values are masked and the footnote says illustrative — read pages.mjs
 * digestPreview() before changing anything that could make a sample look like a real
 * address we published. */
.gw-inbox .frame{background:var(--card);border-radius:var(--r-raise);overflow:hidden;box-shadow:var(--sh-raise),0 2px 0 rgba(255,255,255,.4) inset}
.gw-inbox .chrome{background:var(--night);padding:11px 16px;display:flex;align-items:center;justify-content:space-between;gap:12px}
.gw-inbox .chrome .label{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:rgba(245,242,233,.62)}
.gw-inbox .chrome .dots{display:flex;gap:5px;flex:0 0 auto}
.gw-inbox .chrome .dots i{width:6px;height:6px;border-radius:50%;background:rgba(227,211,174,.3);display:block}
.gw-inbox .body{padding:clamp(18px,2.4vw,26px)}
.gw-inbox .from{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--sea);margin-bottom:8px}
.gw-inbox .subject{font-family:var(--serif);font-size:clamp(19px,2.1vw,23px);font-weight:600;line-height:1.25;letter-spacing:-.012em;color:var(--text);margin-bottom:7px}
.gw-inbox .count{font-family:var(--mono);font-size:11.5px;color:var(--text-3);padding-bottom:16px;border-bottom:1px solid var(--hair-2)}
/* One lead. Trade chip left, index number right, address in Playfair — the address is the
 * product and it is the only serif in the card. */
.gw-lead{padding:18px 0;border-bottom:1px solid var(--hair)}
.gw-lead:last-of-type{border-bottom:0}
.gw-lead .top{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:9px}
.gw-lead .trade{font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;background:rgba(31,138,138,.12);color:var(--sea-ink);padding:4px 8px;border-radius:var(--r);white-space:nowrap}
.gw-lead .idx{font-family:var(--mono);font-size:10.5px;color:var(--text-5)}
.gw-lead .addr{font-family:var(--serif);font-size:clamp(18px,2vw,21px);font-weight:600;letter-spacing:-.01em;color:var(--text);margin-bottom:5px}
.gw-lead .scope{font-size:14px;line-height:1.5;color:var(--text-2);margin-bottom:11px}
/* Valuation and permit number: mono, because they are figures off a government record and
 * should line up like one. */
.gw-lead .facts{display:flex;gap:8px 18px;flex-wrap:wrap;font-family:var(--mono);font-size:11.5px;color:var(--text-3);text-transform:uppercase;letter-spacing:.04em}
.gw-lead .facts b{color:var(--deep);font-weight:500}
.gw-lead .links{display:flex;gap:7px;flex-wrap:wrap;margin-top:11px}
.gw-lead .links a,.gw-lead .links span{font-size:11.5px;color:var(--text-2);text-decoration:none;border:1px solid rgba(14,58,74,.18);border-radius:var(--r);padding:4px 9px}
.gw-lead .links a:hover{border-color:var(--sea);color:var(--sea)}
/* "+ the rest of your week": greyed placeholder ruling where the paid leads would be. It
 * has to read as withheld content, not as a loading state. */
.gw-inbox .rest{padding:16px 0 4px;display:flex;align-items:center;gap:12px}
.gw-inbox .rest .strip{flex:1;height:34px;border-radius:var(--r);background:repeating-linear-gradient(90deg,rgba(14,58,74,.09) 0 46px,rgba(14,58,74,0) 46px 60px)}
.gw-inbox .rest .cap{font-family:var(--mono);font-size:11px;color:var(--text-3);white-space:nowrap}
/* Non-negotiable: the sample is labelled a sample, on the card, in the card's own type. */
.gw-inbox .sample{font-size:12px;line-height:1.5;color:var(--text-4);margin-top:10px}

/* ---------- stat row ----------
 * Four measured figures on the darkest ground, directly under the hero. Two kinds of value:
 * a Playfair number for a figure that is a number, and a mono token underlined in dashes
 * for a value that is a date or a count straight out of stats.json. The dashed underline is
 * the same marker as .gw-mark — it means "this was measured, not written". */
.gw-stats{max-width:var(--shell);margin:0 auto;display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:clamp(24px,3vw,40px)}
.gw-stat b{display:block;font-family:var(--serif);font-size:clamp(32px,4vw,44px);font-weight:600;line-height:1;color:#fffdf7;margin-bottom:9px}
.gw-stat .token{display:inline-block;font-family:var(--mono);font-size:clamp(17px,2.1vw,25px);font-weight:500;line-height:1.15;color:var(--mint);border-bottom:1px dashed rgba(127,208,207,.45);padding-bottom:4px;margin-bottom:11px}
.gw-stat span{display:block;font-size:13.5px;line-height:1.5;color:rgba(245,242,233,.6)}
/* The freshness note under the row — where the numbers came from and when. */
.gw-stats-note{max-width:min(var(--shell),72ch);margin:clamp(24px,3vw,34px) auto 0;padding-top:20px;border-top:1px solid rgba(227,211,174,.14);font-size:13px;line-height:1.6;color:rgba(245,242,233,.5)}

/* ---------- trust bar ----------
 * "Do not take our word for it" + two outline links into the City's own data. It sits on
 * the warm band between the dark stat row and the paper signup so the verification offer
 * lands before the ask, not after it. */
.gw-trust{max-width:var(--shell);margin:0 auto;display:flex;flex-wrap:wrap;gap:16px 36px;align-items:center;justify-content:space-between}
.gw-trust .say{max-width:62ch}
.gw-trust .k{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--sea);margin-bottom:8px}
.gw-trust p{font-size:15.5px;line-height:1.55;color:var(--text);margin:0}
.gw-trust .links{display:flex;gap:10px;flex-wrap:wrap}

/* ---------- free signup card ----------
 * Teal top edge, teal corner ticks, mono header. The only card on the site with a coloured
 * edge, because it is the only free thing on the site. */
.gw-signup{background:var(--card);border:1px solid var(--hair-2);border-top:3px solid var(--sea);border-radius:var(--r);padding:var(--pad-card);box-shadow:var(--sh-card)}
.gw-signup .k{font-family:var(--mono);font-size:var(--t-label);letter-spacing:.14em;text-transform:uppercase;color:var(--sea);margin-bottom:18px}
.gw-signup .done{padding:26px 0}
.gw-signup .done b{display:block;font-family:var(--serif);font-size:24px;font-weight:600;color:var(--deep);margin-bottom:10px}
.gw-signup .done p{font-size:var(--t-body);line-height:1.6;color:var(--text-2);margin:0}
/* The form. Fields are paper-on-cream so they read as fields without a border-heavy box,
 * and the label is a mono caption above the control rather than beside it — one column,
 * one thumb, on a phone. */
.gw-form{display:flex;flex-direction:column;gap:16px}
.gw-form label{display:flex;flex-direction:column;gap:7px;margin:0;font-weight:400;color:inherit;font-size:inherit}
.gw-form label>span{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--text-3);font-weight:400}
.gw-form input,.gw-form select{width:100%;background:var(--paper);border:1px solid rgba(14,58,74,.2);border-radius:var(--r);padding:15px;font-family:var(--sans);font-size:16px;color:var(--text)}
/* 16px is not a taste call: anything smaller and iOS Safari zooms the page on focus. */
.gw-form select{appearance:none;-webkit-appearance:none;padding-right:40px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%235f7178' stroke-width='1.6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 16px center;background-size:12px}
.gw-form button{width:100%;margin:0;background:var(--deep);color:#fffdf7;border:0;border-radius:var(--r);padding:17px 20px;font-family:var(--sans);font-size:16px;font-weight:700;line-height:1.2;cursor:pointer;transition:background .2s ease}
.gw-form button:hover{background:var(--sea)}
/* The live count under the trade select — it changes with the selection, so it is marked
 * like every other measured figure. */
.gw-form .hint{display:flex;flex-wrap:wrap;align-items:baseline;gap:7px;margin:-8px 0 0;font-size:13.5px;line-height:1.5;color:var(--text-2)}
.gw-form .msg{font-size:13.5px;line-height:1.55;color:var(--sea-ink);font-weight:500;margin:0}
.gw-form .terms{font-size:var(--t-fine);line-height:1.55;color:var(--text-4);margin:0}

/* ---------- lists ---------- */
.gw-checks{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:10px}
.gw-checks li{display:flex;gap:11px;align-items:flex-start;font-size:var(--t-body);line-height:1.5;color:var(--gw-head)}
.gw-checks li::before{content:"\2713";flex:0 0 auto;color:var(--gw-accent);font-family:var(--mono)}

/* ---------- comparison columns ----------
 * Them on the left in the warm band colour, us on the right raised on cream with the teal
 * top edge. The asymmetry is the argument; make the two columns identical and the block
 * says nothing.
 *
 * COPY WARNING, not a style note: every Angi and Thumbtack figure printed in here comes
 * from pages.mjs ANGI/COMPETITORS, which derive from Angi's own FY2025 filing and are
 * labelled derived. The "$15–$85 a lead" and "sold to 3–8 contractors" lines that were on
 * the site until 2026-08-12 are retired and must not come back through a redesign. */
.gw-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:clamp(18px,2.4vw,28px)}
.gw-col{background:var(--paper-2);border:1px solid rgba(14,58,74,.12);border-radius:var(--r);padding:clamp(24px,3vw,32px)}
.gw-col.us{background:var(--card);border-color:rgba(31,138,138,.35);border-top:3px solid var(--sea);box-shadow:var(--sh-col)}
.gw-col h3{font-family:var(--mono);font-size:11.5px;font-weight:400;letter-spacing:.14em;text-transform:uppercase;color:var(--text-3);margin:0 0 20px}
.gw-col.us h3{color:var(--sea)}
.gw-col ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:14px}
.gw-col li{position:relative;padding-left:18px;font-size:var(--t-body);line-height:1.55;color:var(--text-2)}
.gw-col li::before{content:"";position:absolute;left:0;top:9px;width:7px;height:1px;background:var(--text-5)}
.gw-col li b{color:var(--text)}
.gw-col.us li{padding-left:20px;color:var(--text)}
.gw-col.us li::before{content:"\2713";top:0;width:auto;height:auto;background:none;color:var(--sea);font-family:var(--mono)}

/* ---------- hairline tile grid ----------
 * Four claims sharing one 1px grid: the gap IS the border, so the tiles read as one table
 * of contents rather than four floating cards. */
.gw-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:1px;background:var(--gw-hair);border:1px solid var(--gw-hair)}
.gw-grid>*{background:var(--gw-ground);padding:var(--pad-tile)}
.gw-grid .n{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;color:var(--gw-accent);margin-bottom:14px}
.gw-grid h3{font-family:var(--serif);font-size:20px;font-weight:600;letter-spacing:-.01em;color:var(--gw-head);margin:0 0 9px}
.gw-grid p{font-size:14.5px;line-height:1.6;color:var(--gw-text);margin:0}

/* ---------- pull quote and testimonial ---------- */
.gw-pull{border-left:3px solid var(--sand);padding:4px 0 4px 22px;margin:0 0 clamp(32px,4vw,48px);max-width:64ch}
.gw-pull p{font-family:var(--serif);font-size:clamp(18px,2.1vw,23px);font-weight:500;line-height:1.42;color:var(--gw-head);margin:0 0 10px}
.gw-pull .after{font-family:var(--sans);font-size:14px;line-height:1.6;color:var(--gw-dim);margin:0}
.gw-quote{background:rgba(255,253,247,.05);border:1px solid var(--edge);border-radius:var(--r);padding:clamp(20px,2.6vw,26px)}
.gw-quote p{font-family:var(--serif);font-style:italic;font-size:clamp(17px,2vw,20px);line-height:1.45;color:#fffdf7;margin:0 0 14px}
.gw-quote .who{font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;color:var(--mint)}
/* A claim panel on a dark ground: teal spine, sand-hairline box. */
.gw-panel{background:rgba(8,34,44,.5);border:1px solid rgba(227,211,174,.22);border-left:3px solid var(--sea);border-radius:var(--r);padding:clamp(22px,3vw,32px)}
.gw-panel .k{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--mint);margin-bottom:12px}
.gw-panel .claim{font-family:var(--serif);font-size:clamp(19px,2.2vw,24px);font-weight:500;line-height:1.35;color:#fffdf7;margin:0 0 14px}
.gw-panel p{font-size:14.5px;line-height:1.65;color:rgba(245,242,233,.62);margin:0 0 16px}
.gw-panel p:last-child{margin-bottom:0}
/* The plain cream card the paper sections use. */
.gw-card{background:var(--card);border:1px solid var(--hair-2);border-radius:var(--r);padding:var(--pad-card)}
.gw-card.band{background:var(--paper-2);border-color:var(--hair-3)}

/* ---------- region / photo cards ----------
 * A place, photographed, with the claim we are allowed to make about it stamped on top.
 * The photo is inset past the section on both ends so a parallax transform never exposes an
 * edge; the two scrims are the hero's, tuned for a shorter block. */
.gw-marker{position:relative;display:flex;align-items:flex-end;overflow:hidden;background:var(--deep);min-height:clamp(340px,47vh,470px)}
.gw-marker.short{min-height:clamp(300px,40vh,400px)}
.gw-marker .photo{position:absolute;inset:-52px 0;z-index:0;pointer-events:none}
.gw-marker.short .photo{inset:-46px 0}
.gw-marker .photo img{width:100%;height:100%;object-fit:cover;display:block}
.gw-marker::before,.gw-marker::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none}
.gw-marker::before{background:linear-gradient(180deg,rgba(8,34,44,.42) 0%,rgba(8,34,44,.55) 42%,rgba(8,34,44,.88) 100%)}
.gw-marker::after{background:linear-gradient(90deg,rgba(8,34,44,.72) 0%,rgba(8,34,44,.34) 46%,rgba(8,34,44,0) 78%)}
.gw-marker .inner{position:relative;z-index:2;width:100%;padding:clamp(26px,3.4vw,40px) var(--gutter) clamp(34px,5vh,52px)}
/* The first marker clears the sticky CTA bar, which otherwise sits on its tag. */
.gw-marker.first .inner{padding-bottom:clamp(80px,12vh,118px)}
.gw-marker .inner>*{max-width:var(--shell);margin-left:auto;margin-right:auto}
.gw-marker .coords{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:14px;font-family:var(--mono);font-size:var(--t-label);letter-spacing:.12em;text-transform:uppercase;color:var(--mint)}
.gw-marker .coords .rule{width:16px;height:1px;background:rgba(227,211,174,.4)}
.gw-marker .coords .dim{color:rgba(245,242,233,.62)}
.gw-marker h3{font-family:var(--serif);font-size:clamp(26px,4vw,42px);font-weight:600;line-height:1.08;letter-spacing:-.02em;color:#fffdf7;margin:0 0 12px}
.gw-marker p{font-size:clamp(15px,1.6vw,17px);line-height:1.6;color:rgba(245,242,233,.78);margin:0 0 16px;max-width:48ch}

/* ---------- tables ----------
 * Mono digits, mono column heads, ink hairlines, no zebra. A permit count has to look like
 * it was read off a record. .scroll on the wrapper, never on the table: a table that cannot
 * scroll sideways breaks the page on a phone instead of itself. */
.gw-table{overflow-x:auto;-webkit-overflow-scrolling:touch;background:var(--paper);border:1px solid var(--hair-2);border-radius:var(--r)}
.gw-paper .gw-table{background:var(--card)}
.gw-table table{width:100%;min-width:560px;margin:0;border:0;border-radius:0;border-collapse:collapse;background:none;font-size:var(--t-body)}
.gw-table.narrow table{min-width:460px}
.gw-table th{text-align:left;vertical-align:bottom;font-family:var(--mono);font-size:10.5px;font-weight:400;letter-spacing:.12em;text-transform:uppercase;color:var(--text-3);background:none;padding:15px 18px;border-bottom:1px solid var(--hair-3)}
.gw-table td{vertical-align:top;padding:16px 18px;border-bottom:1px solid var(--hair);color:var(--text-2)}
.gw-table tbody tr:last-child td{border-bottom:0}
.gw-table td b,.gw-table td a{color:var(--text)}
.gw-table th.n,.gw-table td.n{text-align:right;padding-left:12px;padding-right:12px;font-family:var(--mono);font-variant-numeric:tabular-nums;white-space:nowrap}
.gw-table td.n{color:var(--text)}
.gw-table .total{font-weight:500}
.gw-table td.act{text-align:right;white-space:nowrap}
.gw-table a{text-decoration:none}
.gw-table tbody a:not(.gw-outline){font-weight:700;color:var(--text);text-decoration-color:rgba(31,138,138,.4)}
.gw-table tbody a:not(.gw-outline):hover{color:var(--sea)}

/* ---------- prose pages ----------
 * how-it-works, privacy, terms and the compare pages are paragraphs, not sections. One
 * measure, the redesign's type scale, and nothing else — without it those pages inherit
 * the layer-1 body size and read a full step larger than the rest of the site. */
.gw-prose{max-width:72ch;margin:0 auto;font-size:16px;line-height:1.7;color:var(--text-2);text-wrap:pretty}
.gw-prose h2{font-family:var(--serif);font-size:var(--t-h2-sm);font-weight:600;line-height:1.14;letter-spacing:-.02em;color:var(--text);margin:clamp(38px,5vw,56px) 0 14px}
.gw-prose h3{font-family:var(--serif);font-size:var(--t-h3);font-weight:600;line-height:1.25;letter-spacing:-.01em;color:var(--text);margin:28px 0 8px}
.gw-prose h2 em,.gw-prose h3 em{font-style:italic;font-weight:500;color:var(--sea)}
.gw-prose p{margin:0 0 16px}
.gw-prose ul{padding-left:20px;margin:0 0 16px}
.gw-prose li{margin:8px 0;color:var(--text-2)}
.gw-prose li b,.gw-prose p b{color:var(--text)}
.gw-prose code{font-family:var(--mono);font-size:.92em;background:rgba(14,58,74,.06);padding:1px 5px;border-radius:var(--r)}
.gw-crumb{font-family:var(--mono);font-size:var(--t-label);letter-spacing:.12em;text-transform:uppercase;color:var(--gw-dim);margin:0 0 26px}
.gw-crumb a{color:var(--gw-dim);text-decoration:none}
.gw-crumb a:hover{color:var(--gw-accent)}

/* ---------- footer ----------
 * Dark multi-column: identity, product links, contact, then a mono legal line. Same
 * auto-fit collapse as everything else, so it folds to one column without a breakpoint. */
.gw-footer{background:var(--night);padding:clamp(48px,6vw,76px) var(--gutter) 30px}
.gw-footer .cols{max-width:var(--shell);margin:0 auto;display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:clamp(28px,4vw,48px);padding-bottom:34px;border-bottom:1px solid rgba(227,211,174,.14)}
.gw-footer .gw-brand .mark{width:28px;height:28px;font-size:15px}
.gw-footer .gw-brand .name{font-size:20px}
.gw-footer .about{font-size:14px;line-height:1.6;color:rgba(245,242,233,.55);margin:14px 0 0;max-width:34ch}
.gw-footer h4{font-family:var(--mono);font-size:10.5px;font-weight:400;letter-spacing:.14em;text-transform:uppercase;color:var(--mint);margin:0 0 16px}
.gw-footer .col a{display:block;margin:0 0 11px;font-size:14.5px;color:rgba(245,242,233,.72);text-decoration:none}
.gw-footer .col a:last-child{margin-bottom:0}
.gw-footer .col a:hover{color:#fffdf7}
.gw-footer .col a.tel{font-family:var(--mono);color:var(--paper)}
.gw-footer .legal{max-width:var(--shell);margin:0 auto;padding-top:22px;display:flex;flex-wrap:wrap;gap:12px 28px;justify-content:space-between;font-family:var(--mono);font-size:11px;letter-spacing:.05em;text-transform:uppercase;color:rgba(245,242,233,.42)}
.gw-footer .legal b{color:var(--sand);font-weight:400}

/* ---------- sticky bottom CTA ----------
 * Phone-only by default and visible with no script: on a phone the header CTA is hidden
 * (see [data-hide-sm]) and this bar is the only standing path to the free signup.
 * [data-bar] opts into the scroll-in variant — it starts off-screen and a script sets
 * [data-shown] past the fold. Only add [data-bar] on a page that actually ships that
 * script, or the bar never appears. */
.gw-stickybar{position:fixed;left:0;right:0;bottom:0;z-index:70;display:none;align-items:center;justify-content:space-between;gap:14px;padding:12px clamp(14px,4vw,24px);background:rgba(9,37,48,.96);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border-top:1px solid rgba(227,211,174,.18)}
.gw-stickybar .say{min-width:0}
.gw-stickybar .k{font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--mint);margin-bottom:3px}
.gw-stickybar .line{font-size:14px;font-weight:500;color:var(--paper);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gw-stickybar .gw-btn{flex:0 0 auto;font-size:14px;padding:12px 18px}
.gw-stickybar[data-bar]{transform:translateY(120%);opacity:0;transition:transform .45s cubic-bezier(.22,.61,.36,1),opacity .35s ease}
.gw-stickybar[data-bar][data-shown]{transform:none;opacity:1}
/* The bar is fixed, so it covers the last 72px of the document. The footer pays for it,
 * and only when a bar is actually on the page. */
@media(max-width:760px){
  .gw-stickybar{display:flex}
  body:has(.gw-stickybar) .gw-footer{padding-bottom:96px}
}

/* ---------- responsive ----------
 * The design has exactly one breakpoint pair, 760/761. Everything else folds on its own
 * through auto-fit + minmax, which is why there is so little here. */
@media(max-width:760px){
  [data-hide-sm],.gw-hide-sm{display:none!important}
  [data-sm-1col],.gw-sm-1col{grid-template-columns:1fr!important}
  .gw-cols,.gw-grid,.gw-stats{grid-template-columns:1fr}
  /* The nav wraps under the brand rather than squeezing; the header CTA is hidden on
   * phones because the sticky bar below already carries it. */
  .gw-header .inner{gap:12px}
  .gw-nav{gap:14px 18px;font-size:11.5px}
  .gw-hero{padding-bottom:clamp(48px,14vw,72px)}
  .gw-hero .photo{height:min(52%,420px)}
  .gw-marker,.gw-marker.short{min-height:clamp(300px,58vh,400px)}
  .gw-marker.first .inner{padding-bottom:clamp(56px,9vh,80px)}
  .gw-trust,.gw-split{gap:22px}
  .gw-table table{min-width:0}
  .gw-table th,.gw-table td{padding:12px 14px}
  .gw-footer .legal{flex-direction:column;gap:8px}
  .gw-topbar{font-size:10.5px}
}
@media(min-width:761px){
  [data-hide-lg],.gw-hide-lg{display:none!important}
}

/* ---------- motion ----------
 * Four keyframes, all of them decoration: gwDraw inks the survey contours behind the hero,
 * gwRise brings the inbox preview in once, gwPing is the live dot, gwDrift is the slow
 * float. Nothing in the page's content depends on any of them finishing — an element that
 * animates in must be visible without the animation, or a reduced-motion reader loses it
 * and a crawler indexes an empty page. That is why there is no CSS-only scroll reveal here.
 * The utilities only apply where motion is welcome; the reduce block underneath is the
 * belt to that pair of braces, and also catches motion added inline by a template. */
@keyframes gwDraw{to{stroke-dashoffset:0}}
@keyframes gwRise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
@keyframes gwPing{0%{box-shadow:0 0 0 0 rgba(31,138,138,.4)}70%{box-shadow:0 0 0 12px rgba(31,138,138,0)}100%{box-shadow:0 0 0 0 rgba(31,138,138,0)}}
@keyframes gwDrift{0%,100%{transform:translate3d(0,0,0)}50%{transform:translate3d(0,-10px,0)}}
@media(prefers-reduced-motion:no-preference){
  html{scroll-behavior:smooth}
  /* Set stroke-dasharray/stroke-dashoffset per path inline; the keyframe only runs it to 0. */
  .gw-draw{animation:gwDraw 2.2s ease-out both}
  .gw-rise{animation:gwRise .9s cubic-bezier(.22,.61,.36,1) .25s both}
  .gw-eyebrow .dot{animation:gwPing 2.6s ease-out infinite}
  .gw-drift{animation:gwDrift 9s ease-in-out infinite;will-change:transform}
}
@media(prefers-reduced-motion:reduce){
  /* The negative delay matters: .gw-rise holds its from-state (opacity 0) through its
   * 250ms delay, and zeroing only the DURATION would still blank the inbox preview for a
   * quarter of a second on the machines least able to tolerate it. */
  *,*::before,*::after{animation-duration:.01ms!important;animation-delay:-1ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
}

/* ---------- the design layer's page measure ----------
 * layout({wide:'bleed'}) hands a marketing page the whole viewport: each .gw-section paints its
 * own background band edge to edge and constrains its own content with .gw-shell. Without this
 * the old 900px .wrap would clip every band to a column and the hero photo would end mid-page.
 * main itself gets no padding — the sections carry it, so two adjacent bands never gap. */
main.bleed{display:block;width:100%;padding:0;margin:0;max-width:none}


/* ---- /leads/<trade> funnel (2026-08-21): the form in the hero, the proof under it ---- */
.gw-hero-form{display:flex;flex-wrap:wrap;gap:10px;align-items:stretch;max-width:600px;margin:6px 0 16px}
.gw-hero-form .sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.gw-hero-form input[type=email]{flex:1 1 250px;min-width:0;padding:14px 16px;border-radius:12px;border:1px solid rgba(255,253,247,.28);background:rgba(255,253,247,.96);color:var(--ink);font-size:16px}
.gw-hero-form input[type=email]:focus{outline:3px solid var(--sea);outline-offset:2px}
.gw-hero-form button.gw-btn{margin:0;white-space:nowrap}
.gw-hero-form .msg{flex-basis:100%;margin:4px 0 0;font-weight:700;color:#9fe3d6}
.gw-grid.samples{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
.gw-card.sample .k{font-family:var(--mono);font-size:var(--t-label);letter-spacing:.12em;text-transform:uppercase;color:var(--sea);margin-bottom:10px}
.gw-card.sample .gw-h3{margin:0 0 8px;font-size:clamp(17px,1.6vw,19px);line-height:1.25}
.gw-card.sample .meta{font-size:14px;color:var(--muted);margin:10px 0 8px;line-height:1.5}
.gw-card.sample .meta b{color:var(--deep)}


/* ---- pricing ladder (PRICING_LADDER=1) ---- */
.gw-toggle{display:inline-flex;border:1px solid var(--hair-2);border-radius:999px;padding:4px;margin:10px 0 18px;background:var(--card)}
.gw-toggle button{border:0;background:transparent;padding:8px 14px;border-radius:999px;font-weight:700;color:var(--muted);cursor:pointer}
.gw-toggle button.on{background:var(--deep);color:#fff}
.gw-grid.tiers{grid-template-columns:repeat(auto-fit,minmax(250px,1fr));align-items:stretch}
.gw-card.tier{position:relative;display:flex;flex-direction:column}
.gw-card.tier.best{border-color:var(--sea);box-shadow:0 12px 36px rgba(31,138,138,.16)}
.gw-card.tier .ribbon{position:absolute;top:-12px;left:18px;background:var(--sea);color:#fff;font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;padding:5px 10px;border-radius:999px}
.gw-card.tier .k{font-family:var(--mono);font-size:var(--t-label);letter-spacing:.14em;text-transform:uppercase;color:var(--sea);margin-bottom:8px}
.gw-card.tier .price{font-family:var(--serif);font-size:clamp(40px,5vw,56px);line-height:1;margin:0 0 10px;color:var(--deep)}
.gw-card.tier .price .per{font-family:var(--sans);font-size:15px;color:var(--muted);font-weight:400}
.gw-card.tier .gw-checks{flex:1}
.gw-card.tier .gw-btn{margin-top:14px;align-self:flex-start}
.gw-card.founding{margin-top:16px;border-left:4px solid var(--orange,#e94f1d)}


/* ============================================================================
 * LAYER 3 — THE DESK (2026-09-03).
 *
 * The homepage and /how-it-works are scroll stories: one object, a contractor's clipboard
 * holding this week's real field sheets, pinned in the viewport while the copy scrolls under
 * it. The craft is borrowed from the Fable 5.1 keyboard demo — fixed object on a lerp, giant
 * type behind it, a word-by-word reveal, marquee bands, a repeating two-column beat, a quiet
 * fixed foot. The object is ours, and it is built here in CSS because a permit sheet has to
 * carry live text: a deep-teal board, a steel clip, cream paper, red pen. Every size on the
 * sheet is in cqw so the print scales with the board.
 *
 * Content is never styled into being here: the words on the sheet come from
 * scripts/lib/clipboard.mjs and api/_claim.js. This layer decides only what paper looks like.
 * ========================================================================== */

/* ---------- the story shell ---------- */
body.gw-story{background:radial-gradient(120% 70% at 50% 0%,#faf8f1 0%,var(--paper) 55%,#efebdf 100%) fixed;color:var(--text)}
body.gw-story .gw-topbar{display:none}
body.gw-story .gw-header{position:fixed;top:0;left:0;right:0;z-index:60;background:transparent;border-bottom:1px solid transparent;padding:16px var(--gutter)}
body.gw-story .gw-header[data-stuck]{background:rgba(245,242,233,.74);backdrop-filter:saturate(1.2) blur(14px);-webkit-backdrop-filter:saturate(1.2) blur(14px);border-bottom-color:var(--hair);padding-top:10px;padding-bottom:10px}
body.gw-story .gw-brand .name{color:var(--text)}
body.gw-story .gw-brand .name em{color:var(--sea-ink)}
body.gw-story .gw-nav a{color:var(--text-3)}
body.gw-story .gw-nav a:hover,body.gw-story .gw-nav a[aria-current="page"]{color:var(--text)}
body.gw-story main.bleed{position:relative;z-index:2}

/* The one real click: a thumbnail pill, the demo's shape, pointing at the form-first
 * checkout. The thumb is a tiny clipboard — board, sheet, two printed lines — not an icon. */
.gw-pill{display:inline-flex;align-items:center;gap:10px;padding:4px 14px 4px 4px;border:1px solid var(--hair-2);border-radius:999px;background:rgba(255,253,247,.66);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);font-family:var(--mono);font-size:12px;letter-spacing:-.01em;color:var(--text-3);text-decoration:none;white-space:nowrap}
.gw-pill .thumb{position:relative;width:40px;height:30px;border-radius:999px;background:linear-gradient(160deg,#155166,#0a2a37);overflow:hidden;flex:none}
.gw-pill .thumb i{position:absolute;display:block;background:#fffdf7;border-radius:1px}
.gw-pill .thumb i:nth-child(1){left:12px;top:8px;width:16px;height:22px;box-shadow:0 1px 2px rgba(0,0,0,.3)}
.gw-pill .thumb i:nth-child(2){left:15px;top:14px;width:10px;height:1.5px;background:var(--text-3)}
.gw-pill .thumb i:nth-child(3){left:15px;top:18px;width:7px;height:1.5px;background:var(--text-3)}
.gw-pill .btn{background:var(--deep);color:#fffdf7;padding:9px 14px;border-radius:999px;font-weight:500;transition:background .25s ease}
.gw-pill:hover .btn{background:var(--sea)}
.gw-pill .note{color:var(--text-3)}

/* The quiet fixed foot. Shown on the hero and the close, hidden by the script in between. */
.gw-foot{position:fixed;inset:auto 0 0 0;z-index:30;display:flex;justify-content:space-between;align-items:flex-end;gap:16px;padding:0 24px 22px 22px;font-family:var(--sans);font-size:15px;line-height:1.4;color:var(--text-2);pointer-events:none;transition:opacity .5s ease}
.gw-foot>*{pointer-events:auto}
.gw-foot.hidden{opacity:0}
.gw-foot a{color:var(--text);text-decoration:none;border-bottom:1px solid var(--hair-3)}
.gw-foot a:hover{color:var(--sea-ink);border-bottom-color:var(--sea)}
.gw-foot u{text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--hair-3)}

/* ---------- the object ---------- */
.cb-stage.fixed{position:fixed;left:50%;top:50%;z-index:20;width:min(36vw,470px);pointer-events:none;will-change:transform;transform:translate(-50%,-50%)}
.cb{position:relative;width:100%;aspect-ratio:17/24;container-type:inline-size;transform:rotate(-2.4deg)}
/* The board: deep-teal enamel over a pressed-fibre core. Two long soft shadows, the demo's
 * recipe, so it sits ON the desk rather than floating in a viewport. */
.cb-board{position:absolute;inset:0;border-radius:3.4cqw;background:radial-gradient(130% 90% at 28% 8%,rgba(255,253,247,.14),transparent 58%),repeating-linear-gradient(97deg,rgba(0,0,0,.035) 0 2px,transparent 2px 7px),linear-gradient(160deg,#175468 0%,#0e3a4a 48%,#0a2a37 100%);box-shadow:inset 0 0 0 1px rgba(255,253,247,.14),inset 0 -.6cqw 1.4cqw rgba(0,0,0,.28),0 2.6cqw 3cqw -1cqw rgba(8,34,44,.32),3cqw 7cqw 10cqw -1cqw rgba(8,34,44,.36)}
.cb-sheets{position:absolute;left:6.5cqw;right:6.5cqw;top:9.5cqw;bottom:6cqw;perspective:1400px;transform-style:preserve-3d}
/* A sheet of paper. transform-origin at the top edge, under the clip, so a flip rotates up
 * and away exactly as paper on a clipboard does. The script writes the transform. */
.cb-sheet{position:absolute;inset:0;display:flex;flex-direction:column;z-index:calc(20 - var(--k,0));padding:3.8cqw 4.4cqw 3.2cqw;overflow:hidden;border-radius:.6cqw;background:radial-gradient(140% 100% at 20% 0%,#fffdf7 0%,#f9f5ea 70%,#f3eee1 100%);box-shadow:0 1px 2px rgba(10,43,55,.22),0 8px 22px -12px rgba(10,43,55,.45);transform-origin:50% 0;backface-visibility:hidden;-webkit-backface-visibility:hidden;font-family:var(--mono);color:var(--text);text-wrap:pretty}
.cb-sheet::after{content:"";position:absolute;inset:0;pointer-events:none;background:repeating-linear-gradient(0deg,rgba(10,43,55,.016) 0 1px,transparent 1px 4px)}
/* The clip: a steel spring clip. Hump, bar, jaw, hole — four gradients. */
.cb-clip{position:absolute;left:50%;top:0;width:46cqw;height:12cqw;transform:translateX(-50%);z-index:40}
.cb-clip i{position:absolute;display:block}
.cb-clip .hump{left:50%;top:-4.2cqw;width:15cqw;height:8.4cqw;transform:translateX(-50%);border-radius:7.5cqw 7.5cqw 0 0;background:linear-gradient(90deg,#7f888d 0%,#e8ecee 42%,#b3bbbf 68%,#7f888d 100%);box-shadow:inset 0 -.9cqw 1.4cqw rgba(0,0,0,.28),0 .4cqw .8cqw rgba(0,0,0,.25)}
.cb-clip .bar{left:0;right:0;top:2.4cqw;height:5.6cqw;border-radius:1.3cqw;background:linear-gradient(180deg,#f4f6f7 0%,#c9d0d3 38%,#98a1a6 62%,#d7dde0 100%);box-shadow:0 1.3cqw 1.8cqw -.6cqw rgba(0,0,0,.5),inset 0 .25cqw 0 rgba(255,255,255,.75)}
.cb-clip .jaw{left:7cqw;right:7cqw;top:7.6cqw;height:2.6cqw;border-radius:0 0 1cqw 1cqw;background:linear-gradient(180deg,#b1b9bd,#7a8388);box-shadow:0 .9cqw 1.6cqw rgba(0,0,0,.38)}
.cb-clip .hole{left:50%;top:4.1cqw;width:2.3cqw;height:2.3cqw;margin-left:-1.15cqw;border-radius:50%;background:radial-gradient(circle at 40% 35%,#3c454a,#0b1013);box-shadow:inset 0 .2cqw .4cqw rgba(0,0,0,.6)}

/* ---------- the print on the sheet ---------- */
.cb-head .cb-brand{font-family:var(--serif);font-weight:600;font-size:4.3cqw;line-height:1;letter-spacing:-.01em;color:var(--text)}
.cb-head .cb-brand span{font-family:var(--mono);font-weight:400;font-size:2.15cqw;letter-spacing:.16em;text-transform:uppercase;color:var(--sea-ink);margin-left:1.4cqw;vertical-align:.5em}
.cb-meta{display:flex;flex-wrap:wrap;gap:.4cqw 0;font-size:2.05cqw;letter-spacing:.07em;text-transform:uppercase;color:var(--text-3);margin:1.5cqw 0 0}
.cb-meta span+span::before{content:"·";margin:0 1.4cqw;color:var(--text-5)}
.cb-count{font-family:var(--sans);font-size:2.6cqw;line-height:1.35;color:var(--text-2);margin:2cqw 0 0;padding:1.5cqw 0;border-top:1px solid var(--hair-3);border-bottom:2px solid var(--text)}
.cb-count b{color:var(--text)}
.cb-rows{list-style:none;margin:0;padding:0;flex:1 0 auto}
.cb-row{display:grid;grid-template-columns:4cqw 1fr 13cqw;gap:0 2.2cqw;padding:2.2cqw 0;border-bottom:1px solid var(--hair-2);align-items:start}
.cb-box{position:relative;width:3.2cqw;height:3.2cqw;border:1.5px solid var(--text);border-radius:.4cqw;margin-top:.7cqw}
/* Red pen. The only mark a contractor leaves on the sheet, and it says nothing about anyone. */
.cb-tick{position:absolute;left:-.8cqw;top:-1.6cqw;width:6cqw;height:6cqw;stroke:#b6321f;stroke-width:2.4;fill:none;stroke-linecap:round;stroke-linejoin:round;transform:rotate(-8deg)}
.cb-addr{font-family:var(--sans);font-weight:700;font-size:3.7cqw;line-height:1.12;letter-spacing:-.012em;color:var(--text)}
.cb-zip{font-family:var(--mono);font-weight:400;font-size:2.4cqw;letter-spacing:.04em;color:var(--text-3);margin-left:.6cqw}
.cb-scope{font-family:var(--sans);font-size:2.5cqw;line-height:1.32;color:var(--text-2);margin:.7cqw 0 0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.cb-line{display:flex;flex-wrap:wrap;gap:.3cqw 1.8cqw;font-size:2.15cqw;letter-spacing:.02em;color:var(--text-3);margin:.9cqw 0 0}
.cb-line .cb-num,.cb-num{color:var(--text);font-weight:500}
.cb-trade{color:var(--sea-ink);text-transform:uppercase;letter-spacing:.12em;font-size:2cqw}
.cb-val{color:var(--text)}
.cb-rowclaim{font-size:1.8cqw;letter-spacing:.14em;text-transform:uppercase;color:var(--sea-ink);margin:.9cqw 0 0}
.cb-ph{display:flex;flex-direction:column;align-items:flex-end;gap:.9cqw;padding-top:.6cqw;text-align:right;font-size:1.9cqw;letter-spacing:.1em;text-transform:uppercase;color:var(--text-4)}
/* The stamp. The paid sheet differs here; the free sheet says so in red ink and never in digits. */
.cb-paid{display:inline-block;border:1.5px solid rgba(182,50,31,.6);color:#b6321f;border-radius:.4cqw;padding:.55cqw 1cqw;font-size:1.85cqw;letter-spacing:.14em;font-weight:500;transform:rotate(-5deg);white-space:nowrap}
.cb-foot{margin-top:auto;padding-top:2cqw}
.cb-claim{font-family:var(--sans);font-size:2.4cqw;line-height:1.35;color:var(--text);margin:0}
.cb-claim b{font-family:var(--mono);font-weight:500;font-size:2.1cqw;letter-spacing:.12em;color:var(--sea-ink)}
.cb-fine{font-family:var(--sans);font-size:2.05cqw;line-height:1.35;color:var(--text-4);margin:.9cqw 0 0}

/* The Orange County sheet has one line per city; tighter, no scope, so eight lines fit. */
.cb-sheet.oc .cb-row{padding:1.9cqw 0;grid-template-columns:3.4cqw 1fr 12cqw}
.cb-sheet.oc .cb-scope{display:none}
.cb-sheet.oc .cb-addr{font-size:3cqw}
.cb-sheet.oc .cb-rowclaim{display:none}
.cb-sheet.oc .cb-box{width:2.8cqw;height:2.8cqw}

/* The City's file, as it arrives: a five-column table in the CSV's own column names. */
.cb-raw{width:100%;table-layout:fixed;border-collapse:collapse;margin:2.2cqw 0 0;font-size:1.85cqw;line-height:1.3;background:transparent;border:0;border-radius:0;flex:1 0 auto}
.cb-raw th:nth-child(1){width:18%}.cb-raw th:nth-child(2){width:12%}.cb-raw th:nth-child(3){width:30%}.cb-raw th:nth-child(4){width:25%}.cb-raw th:nth-child(5){width:15%}
.cb-raw th,.cb-raw td{padding:1.4cqw .6cqw;border-bottom:1px solid var(--hair-2);text-align:left;vertical-align:top;background:transparent;font-size:1.85cqw;line-height:1.3;overflow-wrap:anywhere}
.cb-raw th{font-weight:500;font-size:1.5cqw;letter-spacing:.02em;text-transform:none;color:var(--text-3);border-bottom:2px solid var(--text);overflow-wrap:anywhere;word-break:break-all}
.cb-raw td{color:var(--text-2)}
.cb-raw td:first-child{color:var(--text);font-weight:500}
.cb-holder{color:var(--sea-ink)}
.cb-holder .cb-tick{position:static;display:inline-block;width:2.8cqw;height:2.8cqw;vertical-align:middle;transform:none;stroke-width:3}

/* The check sheet: the permit number is the line. */
.cb-rows.check .cb-row{grid-template-columns:4cqw 1fr;padding:3.2cqw 0}
.cb-addr.big{font-family:var(--mono);font-weight:500;font-size:5cqw;letter-spacing:.02em}
.cb-line.dim{color:var(--sea-ink)}

/* ---------- the sheet in flow (/leads) ---------- */
.cb-stage.static{position:relative;width:100%;max-width:920px;margin:clamp(22px,3.4vw,40px) auto 0;pointer-events:auto}
.cb-stage.static .cb{aspect-ratio:auto;transform:rotate(-.6deg)}
.cb-stage.static .cb-board{inset:0}
.cb-stage.static .cb-board{border-radius:16px;box-shadow:inset 0 0 0 1px rgba(255,253,247,.14),inset 0 -3px 7px rgba(0,0,0,.28),0 14px 16px -6px rgba(8,34,44,.3),16px 36px 60px -8px rgba(8,34,44,.32)}
.cb-stage.static .cb-sheets{position:relative;inset:auto;margin:58px 30px 30px;perspective:none;transform-style:flat}
/* The clip in px on the in-flow board: cqw there is relative to a 900px frame. */
.cb-stage.static .cb-clip{width:220px;height:58px}
.cb-stage.static .cb-clip .hump{top:-20px;width:72px;height:40px;border-radius:36px 36px 0 0;box-shadow:inset 0 -4px 7px rgba(0,0,0,.28),0 2px 4px rgba(0,0,0,.25)}
.cb-stage.static .cb-clip .bar{top:12px;height:27px;border-radius:6px;box-shadow:0 6px 9px -3px rgba(0,0,0,.5),inset 0 1px 0 rgba(255,255,255,.75)}
.cb-stage.static .cb-clip .jaw{left:34px;right:34px;top:37px;height:12px;border-radius:0 0 5px 5px;box-shadow:0 4px 8px rgba(0,0,0,.38)}
.cb-stage.static .cb-clip .hole{top:20px;width:11px;height:11px;margin-left:-5.5px;box-shadow:inset 0 1px 2px rgba(0,0,0,.6)}
.cb-sheet.flat{position:relative;inset:auto;display:block;padding:clamp(18px,3.2vw,34px) clamp(18px,3.4vw,36px);border-radius:3px}
.cb-sheet.flat .cb-brand{font-size:clamp(20px,2.6vw,26px)}
.cb-sheet.flat .cb-brand span{font-size:11px;margin-left:10px}
.cb-sheet.flat .cb-meta{font-size:11.5px;margin-top:10px}
.cb-sheet.flat .cb-meta span+span::before{margin:0 8px}
.cb-sheet.flat .cb-count{font-size:14.5px;margin-top:14px;padding:11px 0}
.cb-sheet.flat .cb-foot{padding-top:16px}
.cb-sheet.flat .cb-claim{font-size:14.5px}
.cb-sheet.flat .cb-claim b{font-size:11px}
.cb-sheet.flat .cb-fine{font-size:12.5px;margin-top:6px}
.cb-sheet.flat .gw-grid.samples{display:block;background:transparent;border:0;margin:0;gap:0}
.cb-sheet.flat .gw-card.sample{background:transparent;border:0;border-bottom:1px solid var(--hair-2);border-radius:0;padding:18px 0 16px;box-shadow:none}
.cb-sheet.flat .gw-card.sample .gw-h3{font-family:var(--sans);font-weight:700;letter-spacing:-.012em;font-size:clamp(17px,1.8vw,21px)}
.cb-sheet.flat .gw-card.sample .gw-copy{font-family:var(--sans);font-size:14.5px;margin-bottom:8px}
.cb-sheet.flat .gw-card.sample .gw-fine{font-family:var(--sans)}
.cb-sheet.flat .gw-card.sample .meta{font-family:var(--mono);font-size:12.5px;margin:6px 0 6px}
.cb-sheet.flat .gw-card.sample .gw-fine{margin-top:6px}

/* ---------- the story sections ---------- */
.gw-story-hero{position:relative;height:100vh;height:100svh;display:flex;flex-direction:column;justify-content:flex-end;padding:0 0 11vh;overflow:hidden}
.gw-story-tag{position:absolute;top:100px;left:var(--gutter);max-width:250px;margin:0;font-family:var(--sans);font-size:17px;line-height:1.25;letter-spacing:-.01em;color:var(--text-2)}
.gw-giant{font-family:var(--serif);font-weight:600;font-size:13.2vw;line-height:.86;letter-spacing:-.035em;white-space:nowrap;padding-left:1.6vw;margin:0;color:var(--text);will-change:transform,opacity}
.gw-giant .l{display:block}
.gw-giant.close{font-size:13.5vw;opacity:0}
.gw-statement{height:170vh}
.gw-statement .sticky{position:sticky;top:0;height:100vh;height:100svh;display:flex;align-items:center;padding:0 var(--gutter)}
.gw-reveal{font-family:var(--sans);font-weight:500;font-size:clamp(22px,2.35vw,31px);line-height:1.25;letter-spacing:-.012em;color:var(--text);margin:0}
.gw-reveal .w{opacity:.12;transition:opacity .15s linear}
.gw-reveal .o{color:var(--sea)}
.gw-reveal b{font-weight:600}
.gw-statement .gw-reveal{max-width:640px;margin-left:clamp(0px,4vw,80px)}
.gw-center{height:120vh}

/* Marquee bands, in the display face. The mark between repeats is a permit stamp. */
.gw-mq{overflow:hidden;white-space:nowrap;padding:22vh 0 8vh;position:relative;z-index:5}
.gw-mq .track{display:inline-flex;align-items:center;animation:gw-mq var(--dur,60s) linear infinite}
.gw-mq.rev .track{animation-direction:reverse}
.gw-mq span{font-family:var(--serif);font-weight:600;font-size:8.4vw;line-height:.9;letter-spacing:-.025em;padding-right:44px;color:var(--text)}
.gw-mq .ic{width:.72em;height:.72em;font-size:8.4vw;margin-right:44px;flex:none;display:inline-block;color:var(--sea)}
.gw-mq .ic svg{width:100%;height:100%;display:block}
@keyframes gw-mq{to{transform:translateX(-50%)}}

/* A beat: reveal paragraph, then the two columns. Left-set, the board holds the right. */
.gw-beat{display:flex;justify-content:flex-start;padding:15vh var(--gutter) 11vh}
.gw-beat .inner{width:min(600px,47vw);margin-left:clamp(0px,6vw,120px)}
.gw-beat .gw-reveal{margin-bottom:34px}
.gw-beat .cols{display:grid;grid-template-columns:1fr 1fr;gap:34px}
.gw-beat h4{font-family:var(--mono);font-size:11px;font-weight:400;letter-spacing:.14em;text-transform:uppercase;color:var(--text-3);margin:0 0 12px}
.gw-beat .cols p{font-family:var(--sans);font-size:15px;line-height:1.62;color:var(--text-2);margin:0}
.gw-beat .cols a{color:var(--text)}
.gw-beat code{font-family:var(--mono);font-size:.9em;background:rgba(14,58,74,.07);padding:1px 5px;border-radius:2px;color:var(--text)}
.gw-beat .beat-links{margin:26px 0 0;gap:10px}
.gw-outline.solid{background:var(--deep);color:#fffdf7;border-color:var(--deep)}
.gw-outline.solid:hover{background:var(--sea);border-color:var(--sea);color:#fffdf7}

/* The week's lines, one card each, on a slow track — the honest stand-in for a review row. */
.gw-ticker-wrap{position:relative;z-index:5;padding:10vh 0 12vh}
.gw-ticker-k{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-3);text-align:center;margin:0 0 28px}
.gw-ticker{overflow:hidden;-webkit-mask-image:linear-gradient(to right,transparent 0,#000 15%,#000 85%,transparent 100%);mask-image:linear-gradient(to right,transparent 0,#000 15%,#000 85%,transparent 100%)}
.gw-ticker .track{display:flex;gap:22px;width:max-content;animation:gw-mq 110s linear infinite}
.gw-ticker .card{width:300px;flex:none;background:var(--card);border:1px solid var(--hair-2);border-radius:3px;padding:20px 20px 18px;box-shadow:0 1px 2px rgba(10,43,55,.1),0 18px 40px -28px rgba(10,43,55,.5)}
.gw-ticker .card .k{display:flex;justify-content:space-between;gap:10px;font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--sea-ink);margin:0 0 14px}
.gw-ticker .card .k em{font-style:normal;color:var(--text-4);letter-spacing:.06em}
.gw-ticker .card q{quotes:none;display:block;font-family:var(--sans);font-weight:700;font-size:20px;line-height:1.2;letter-spacing:-.012em;color:var(--text);margin:0 0 8px}
.gw-ticker .card p{font-size:13.5px;line-height:1.45;color:var(--text-2);margin:0 0 14px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.gw-ticker .card .who{display:flex;flex-wrap:wrap;gap:6px 14px;font-family:var(--mono);font-size:11.5px;color:var(--text-3)}
.gw-ticker .card .who .lab{color:var(--sea-ink);letter-spacing:.1em;font-size:10px;width:100%}

.gw-closing{height:150vh}
.gw-closing .sticky{position:sticky;top:0;height:100vh;height:100svh;display:flex;flex-direction:column;justify-content:flex-end;padding-bottom:10vh;overflow:hidden}

/* After the story the page is a desk again: the free form, the table, the price, the owner. */
.gw-desk{border-top:1px solid var(--hair);position:relative;z-index:6}
body.gw-story .gw-section{position:relative;z-index:6}
body.gw-story .gw-signup{box-shadow:0 1px 2px rgba(10,43,55,.12),0 24px 50px -30px rgba(10,43,55,.5)}

/* ---------- narrow screens ----------
 * The board goes behind the copy (the demo does the same with its keyboard), scaled down, and
 * the copy sits on frosted paper so it stays legible over it. The fixed foot yields to the
 * sticky signup bar. */
@media(max-width:820px){
  .cb-stage.fixed{width:min(78vw,380px);z-index:1}
  /* The board is INSIDE <main>, so the copy has to be positioned to paint over it. */
  .gw-statement,.gw-beat,.gw-ticker-wrap,.gw-mq,.gw-closing{position:relative;z-index:3}
  .gw-foot{display:none}
  .gw-story-tag{display:none}
  body.gw-story .gw-nav{display:none}
  .gw-giant{font-size:15.5vw}
  .gw-giant.close{font-size:15vw}
  .gw-reveal{font-size:22px}
  .gw-statement .gw-reveal,.gw-beat .inner{max-width:100%;width:100%;margin-left:0;background:rgba(245,242,233,.8);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);padding:20px;border-radius:6px;border:1px solid var(--hair)}
  .gw-beat{padding:10vh var(--gutter) 8vh}
  .gw-beat .cols{grid-template-columns:1fr;gap:22px}
  .gw-mq span,.gw-mq .ic{font-size:11vw}
  .gw-pill .note{display:none}
}
@media(max-width:560px){
  .gw-pill{padding:3px 3px}
  .gw-pill .thumb{display:none}
  .gw-pill .btn{padding:8px 12px}
}
@media (prefers-reduced-motion:reduce){
  .gw-mq .track,.gw-ticker .track{animation:none}
  .gw-reveal .w{opacity:1!important}
  .gw-foot{transition:none}
}
