/* Self-hosted, so the page loads nothing from anywhere else. Bricolage Grotesque and
   IBM Plex Sans and Mono are both under the SIL Open Font License 1.1; see
   FONT-LICENSE.md. Latin subsets only, from the @fontsource packages. */
@font-face{font-family:"Bricolage Grotesque";font-style:normal;font-weight:800;font-display:swap;src:url("fonts/bricolage-grotesque-latin-800-normal.woff2") format("woff2");}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:400;font-display:swap;src:url("fonts/ibm-plex-sans-latin-400-normal.woff2") format("woff2");}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:500;font-display:swap;src:url("fonts/ibm-plex-sans-latin-500-normal.woff2") format("woff2");}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:600;font-display:swap;src:url("fonts/ibm-plex-sans-latin-600-normal.woff2") format("woff2");}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url("fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2");}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url("fonts/ibm-plex-mono-latin-500-normal.woff2") format("woff2");}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:600;font-display:swap;src:url("fonts/ibm-plex-mono-latin-600-normal.woff2") format("woff2");}

/* Mappr by ARGH!
   Every colour here is read from src/app.html at 1.10.1, except Ash, which is
   body copy on the site where Ink is too bright at length and Muted too dim.
   If the app's dark palette changes, these change with it. The app is the source. */

:root{
  --field:#121212;
  --panel:#1e1e1e;
  --line:#343434;
  --ink:#e3e3e3;
  --ash:#b9bcc0;
  --muted:#8d949b;

  --blue:#74c0fc;
  --yellow:#ffd43b;
  --green:#69db7c;
  --orange:#ffa94d;
  --violet:#b197fc;
  --red:#ff8787;

  --rule-page:rgba(160,195,230,.07);
  --rule-map:rgba(160,195,230,.10);
  --rule-map-strong:rgba(160,195,230,.19);

  --display:'Bricolage Grotesque',system-ui,sans-serif;
  --sans:'IBM Plex Sans',system-ui,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,monospace;

  --page-max:1200px;
  --gut:48px;
}

*{box-sizing:border-box}

html{scroll-behavior:smooth}

body{
  margin:0;
  background-color:var(--field);
  /* the page grid: three times coarser and lighter than the map, so the map
     reads as the working zoom and the page as the same paper further out */
  background-image:
    linear-gradient(var(--rule-page) 1px, transparent 1px),
    linear-gradient(90deg, var(--rule-page) 1px, transparent 1px);
  background-size:60px 60px, 60px 60px;
  color:var(--ink);
  font-family:var(--sans);
  font-size:15px;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
}

a{color:var(--blue);text-decoration:none}
a:hover{color:var(--ink)}

h1,h2,h3{font-family:var(--display);font-weight:800;margin:0}
p{margin:0}

/* ---------- shared ---------- */

.wrap{max-width:var(--page-max);margin:0 auto;padding:0 var(--gut)}

.label{
  font-family:var(--mono);font-weight:600;font-size:10px;
  letter-spacing:1.8px;color:var(--muted);text-transform:uppercase;
}

.lead{font-size:17px;line-height:1.6;color:var(--ash);max-width:620px}
.body{font-size:15px;line-height:1.65;color:var(--ash);max-width:620px}
.small{font-size:13px;line-height:1.55;color:var(--ash)}

.key{
  display:inline-flex;align-items:center;
  font-family:var(--mono);font-weight:600;font-size:12px;
  background:var(--field);border:1px solid var(--line);
  padding:5px 10px;border-radius:4px;white-space:nowrap;
}
.key.blue{color:var(--blue)} .key.yellow{color:var(--yellow)}
.key.green{color:var(--green)} .key.violet{color:var(--violet)}
.key.red{color:var(--red)}

.btn{
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--mono);font-size:13px;font-weight:600;
  padding:13px 24px;border-radius:4px;border:1px solid transparent;
  min-height:44px;cursor:pointer;
}
/* text on any accent is Field, never Ink: Ink on an accent is 1.1 to 1.9 to 1 */
.btn-primary{background:var(--ink);color:var(--field)}
.btn-primary:hover{background:#fff;color:var(--field)}
.btn-ghost{color:var(--ink);border-color:var(--line);font-weight:400}
.btn-ghost:hover{color:var(--ink);border-color:var(--muted)}

.section{padding:76px 0}
.section-head{
  display:flex;gap:40px;align-items:flex-end;
  margin-bottom:34px;flex-wrap:wrap;
}
.section-head h2{font-weight:700;font-size:46px;line-height:1;letter-spacing:-.8px;max-width:620px}
.section-head .label{display:block;margin-bottom:14px}
.section-head .side{width:420px;max-width:100%;font-size:15px;line-height:1.65;color:var(--ash)}
.section-head .hgroup{flex:1 1 380px;min-width:0}

.card{
  background:var(--panel);border:1px solid var(--line);
  border-radius:4px;padding:26px 24px;
}
.card h3{font-weight:600;font-size:20px;margin-bottom:8px}

/* the map paper, wherever a panel shows one */
.map-paper{
  background-color:var(--field);
  background-image:
    linear-gradient(var(--rule-map) 1px, transparent 1px),
    linear-gradient(90deg, var(--rule-map) 1px, transparent 1px),
    linear-gradient(var(--rule-map-strong) 1px, transparent 1px),
    linear-gradient(90deg, var(--rule-map-strong) 1px, transparent 1px);
  background-size:20px 20px, 20px 20px, 100px 100px, 100px 100px;
}

.panel{
  background:var(--panel);border:1px solid var(--line);
  border-radius:6px;overflow:hidden;
}
.panel-bar{
  height:34px;border-bottom:1px solid var(--line);
  display:flex;align-items:center;padding:0 14px;gap:10px;
  font-family:var(--mono);font-size:10px;color:#4f4f4f;
  overflow-x:auto;scrollbar-width:none;
}
.panel-bar::-webkit-scrollbar{display:none}
.panel-bar .tab{color:var(--muted);white-space:nowrap}
.panel-bar .tab.on{color:var(--ink);border-bottom:2px solid var(--yellow);padding-bottom:2px}
.panel-bar .spacer{flex-grow:1}
.panel-bar .chip{
  font-family:var(--mono);font-size:10px;font-weight:600;
  border:1px solid var(--line);background:var(--field);
  padding:3px 8px;border-radius:3px;white-space:nowrap;color:var(--muted);
}
.panel-bar .count{color:var(--muted);white-space:nowrap}

/* ---------- the spectrum rule ---------- */

.spectrum{height:6px;display:flex}
.spectrum span{flex-grow:1}
.spectrum .s1{background:var(--red)}
.spectrum .s2{background:var(--orange)}
.spectrum .s3{background:var(--yellow)}
.spectrum .s4{background:var(--green)}
.spectrum .s5{background:var(--blue)}
.spectrum .s6{background:var(--violet)}

/* ---------- top bar ---------- */

.topbar{
  position:sticky;top:0;z-index:20;
  background:var(--panel);border-bottom:1px solid var(--line);
}
.topbar .inner{
  max-width:var(--page-max);margin:0 auto;
  height:56px;display:flex;align-items:center;gap:14px;padding:0 var(--gut);
}
.topbar .name{font-family:var(--display);font-weight:700;font-size:19px}
.topbar .ver{
  font-family:var(--mono);font-size:10px;color:var(--muted);
  border:1px solid var(--line);padding:2px 6px;border-radius:3px;
}
.topbar nav{margin-left:auto;display:flex;align-items:center;gap:18px}
.topbar nav a{font-family:var(--mono);font-size:12px;color:var(--muted)}
.topbar nav a:hover{color:var(--ink)}
.topbar nav a.argh{color:var(--yellow)}
.topbar nav a.cta{
  color:var(--field);background:var(--yellow);font-weight:600;
  padding:8px 13px;border-radius:4px;
}
.topbar nav a.cta:hover{color:var(--field);filter:brightness(1.08)}

/* ---------- hero ---------- */

.hero{padding:56px 0 0;text-align:center}
.hero .label{letter-spacing:2.4px}
.hero h1{
  font-weight:700;font-size:76px;line-height:.94;letter-spacing:-1.6px;
  margin:18px auto 0;
}
.hero h1 .hl{color:var(--yellow)}
.hero .lead{margin:18px auto 0;max-width:600px}
.hero .actions{display:flex;gap:10px;justify-content:center;margin-top:22px;flex-wrap:wrap}
.hero .reassure{
  display:block;margin-top:14px;
  font-family:var(--mono);font-size:11px;color:var(--muted);
}
.hero-panel{
  margin-top:38px;
  /* the panel closes: it is a window onto the map, not a cut-off one */
}
.hero-panel .stage{
  height:300px;display:flex;align-items:center;justify-content:center;padding:10px;
}
.hero-panel .stage svg{width:100%;height:100%;max-height:260px}

/* ---------- 02, the demo panel ---------- */

.demo-panel{height:460px;display:flex;flex-direction:column}
.demo-panel .md-stage{flex:1 1 auto;min-height:0;position:relative}
.demo-panel .md-stage svg{display:block;width:100%;height:100%}
.demo-caption{
  margin-top:12px;display:flex;gap:18px;flex-wrap:wrap;
  font-family:var(--mono);font-size:11px;color:var(--muted);
}
.panel-bar .chip.hot{
  color:var(--ink);border-color:var(--ink);background:#262626;
}
.panel-bar .chip{transition:color .18s ease,border-color .18s ease,background-color .18s ease}

/* ---------- 03, philosophy ---------- */

.pillars{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
.pillar{display:flex;flex-direction:column;gap:14px;border-top-width:3px;border-top-style:solid}
.pillar.p1{border-top-color:var(--blue)}
.pillar.p2{border-top-color:var(--yellow)}
.pillar.p3{border-top-color:var(--green)}
.pillar .n{font-family:var(--mono);font-size:11px}
.pillar.p1 .n{color:var(--blue)} .pillar.p2 .n{color:var(--yellow)} .pillar.p3 .n{color:var(--green)}
.pillar .head{display:flex;align-items:baseline;gap:10px}
.pillar h3{font-size:26px}
.pillar p{font-size:14px;line-height:1.65;color:var(--ash)}
.pillar .rule{
  margin-top:auto;border-top:1px solid var(--line);padding-top:14px;
  font-family:var(--mono);font-size:11px;line-height:1.7;color:var(--muted);
}
.closing{display:flex;align-items:center;gap:14px;margin-top:28px;flex-wrap:wrap}
.closing span{font-size:14px;color:var(--ash)}

/* ---------- 04, how it works ---------- */

.keys{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px;margin-bottom:14px}
.keycard{padding:20px;display:flex;flex-direction:column;gap:14px}
.keycard .key{align-self:flex-start;font-size:13px;padding:8px 13px}
.keycard h3{font-size:19px;margin-bottom:7px}
.keycard p{font-size:13px;line-height:1.6;color:var(--ash)}

.how-lower{display:grid;grid-template-columns:380px minmax(0,1fr);gap:14px}
.storage{padding:24px;display:flex;flex-direction:column;gap:16px}
.storage .label{color:var(--green)}
.storage .top{display:flex;align-items:center;gap:14px}
.storage .top p{font-size:14px;line-height:1.6;color:var(--ash)}
.storage ul{list-style:none;margin:0;padding:14px 0 0;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:9px}
.storage li{display:flex;gap:9px;font-size:13px;color:var(--ash)}
.storage li .m{font-family:var(--mono);font-size:12px;flex-shrink:0}
.storage li.plus .m{color:var(--green)}
.storage li.warn .m{color:var(--orange)}
.story-stage{min-height:280px;display:flex;align-items:center;justify-content:center;padding:12px}
.story-stage svg{width:100%;height:auto;max-height:240px}

/* ---------- 05, community ---------- */

.community{display:grid;grid-template-columns:452px minmax(0,1fr);gap:16px}
.news{border-top:3px solid var(--yellow);display:flex;flex-direction:column;gap:16px}
.news h3{font-size:24px}
.news p{font-size:14px;line-height:1.6;color:var(--ash)}
.news form{display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap}
.news .field{flex:1 1 200px;display:flex;flex-direction:column;gap:7px}
.news label{font-family:var(--mono);font-size:10px;letter-spacing:1.4px;color:var(--muted)}
.news input{
  height:44px;background:var(--field);border:1px solid var(--line);
  border-radius:4px;color:var(--ink);font-size:14px;padding:0 14px;font-family:var(--sans);
}
.news input:focus{outline:2px solid var(--blue);outline-offset:1px}
.news button{
  height:44px;font-family:var(--mono);font-size:13px;font-weight:600;
  color:var(--field);background:var(--yellow);border:none;padding:0 20px;
  border-radius:4px;cursor:pointer;
}
.news button:hover{filter:brightness(1.08)}
.news .foot{margin-top:auto;font-family:var(--mono);font-size:11px;color:var(--muted)}

.links{display:flex;flex-direction:column;gap:12px}
.linkcard{
  flex:1 1 0;background:var(--panel);border:1px solid var(--line);
  border-radius:4px;padding:18px 20px;display:flex;align-items:center;gap:16px;
  border-left-width:3px;border-left-style:solid;color:var(--ink);
}
.linkcard:hover{background:#242424;color:var(--ink)}
.linkcard.violet{border-left-color:var(--violet)}
.linkcard.blue{border-left-color:var(--blue)}
.linkcard.red{border-left-color:var(--red)}
.linkcard .t{font-family:var(--display);font-weight:600;font-size:18px;margin-bottom:3px}
.linkcard .d{font-size:13px;color:var(--ash)}
.linkcard .arrow{font-family:var(--mono);font-size:14px}
.linkcard.violet .arrow{color:var(--violet)}
.linkcard.blue .arrow{color:var(--blue)}
.linkcard.red .arrow{color:var(--red)}
.linkcard .grow{flex-grow:1}

/* ---------- footer ---------- */

footer{
  border-top:1px solid var(--line);background:rgba(30,30,30,.6);
  margin-top:56px;padding:26px 0;
}
footer .inner{
  max-width:var(--page-max);margin:0 auto;padding:0 var(--gut);
  display:flex;gap:40px;align-items:flex-start;flex-wrap:wrap;
}
footer .brand{width:300px}
footer .lockup{display:flex;align-items:center;gap:11px;margin-bottom:10px}
footer .lockup .name{font-family:var(--display);font-weight:700;font-size:18px}
footer .lockup .by{font-family:var(--mono);font-size:11px;color:var(--muted)}
footer .brand .t{font-size:13px;line-height:1.6;color:var(--muted)}
footer .cols{flex-grow:1;display:flex;gap:60px;flex-wrap:wrap}
footer .col{display:flex;flex-direction:column;gap:9px}
footer .col .h{font-family:var(--mono);font-size:10px;letter-spacing:1.4px;color:var(--muted)}
footer .col a{font-size:13px;color:var(--ash)}
footer .col a:hover{color:var(--ink)}
footer .col span{font-size:13px;color:var(--muted)}

/* ---------- narrower ---------- */

@media (max-width:1000px){
  :root{--gut:28px}
  .hero h1{font-size:56px;letter-spacing:-1px}
  .section-head h2{font-size:36px}
  .pillars,.keys{grid-template-columns:repeat(2,minmax(0,1fr))}
  .how-lower,.community{grid-template-columns:minmax(0,1fr)}
  .section{padding:64px 0}
}

@media (max-width:640px){
  :root{--gut:16px}
  .hero h1{font-size:40px;line-height:1;letter-spacing:-.6px;max-width:none}
  .section-head h2{font-size:30px}
  .pillars,.keys{grid-template-columns:minmax(0,1fr)}
  .topbar nav{gap:12px}
  .topbar nav a:not(.cta):not(.argh){display:none}
  .hero-panel .stage{height:200px}
  .demo-panel{height:340px}
  .section{padding:52px 0}
}

@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  .panel-bar .chip{transition:none}
}

/* Excalifont, the hand-drawn face Excalidraw ships, under the SIL Open Font
   License 1.1. See FONT-LICENSE.md. It stays inside the map: it never sets
   interface text. */
@font-face{
  font-family:"Excalifont";
  src:url("Excalifont-Regular.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;
}

/* ---------- hero note ---------- */

.hero-note{
  margin-top:10px;font-family:var(--mono);font-size:11px;color:var(--muted);
}

/* ---------- the map panel, wherever it runs ---------- */

.md-stage{flex:1 1 auto;min-height:0;position:relative}
.md-stage svg{display:block;width:100%;height:100%}
.hero-panel{display:flex;flex-direction:column}
.hero-panel .md-stage{height:320px;padding:0}

/* ---------- 02, the outline exchange ---------- */

.exchange{
  display:grid;
  grid-template-columns:minmax(0,340px) auto minmax(0,1fr);
  gap:18px;align-items:stretch;
}
.ex-text{display:flex;flex-direction:column}
.outline{
  margin:0;flex-grow:1;padding:22px 24px;
  display:flex;flex-direction:column;justify-content:center;
  font-family:var(--mono);font-size:14px;line-height:2;
  color:var(--ink);white-space:pre;overflow-x:auto;
}
.outline .mk{color:var(--muted)}

.ex-arrows{
  display:flex;flex-direction:column;justify-content:center;gap:22px;
  padding:0 2px;
}
.ex-arrow{display:flex;flex-direction:column;align-items:center;gap:6px}
.ex-arrow .g{font-family:var(--mono);font-size:22px;line-height:1;color:var(--ash)}
.ex-arrow .t{font-family:var(--mono);font-size:10px;letter-spacing:1.4px;color:var(--muted)}
.ex-arrow .key{font-size:11px;padding:4px 8px}

.ex-map{display:flex;flex-direction:column}
.ex-stage{flex-grow:1;min-height:300px;display:flex;align-items:center;justify-content:center;overflow:hidden}
.ex-stage svg{display:block;width:100%;height:100%;padding:18px}

@media (max-width:1000px){
  .exchange{grid-template-columns:minmax(0,1fr)}
  .ex-arrows{flex-direction:row;justify-content:center;gap:40px}
  .ex-arrow .g{transform:rotate(90deg)}
  .ex-arrow:last-child .g{transform:rotate(-90deg)}
  .hero-panel .md-stage{height:260px}
}
@media (max-width:640px){
  .hero-panel .md-stage{height:220px}
  .ex-stage{min-height:220px}
}


/* ---------- Bricolage Grotesque, one display face across ARGH! and every tool
   (settled 22 Sept 2026). 800 is the only display weight; the tighter tracking
   below is the face's, not a style choice. ---------- */

.hero h1{font-weight:800;letter-spacing:-2.8px}
.section-head h2{font-weight:800;letter-spacing:-1.4px}
.topbar .name{font-weight:800;letter-spacing:-.6px;font-size:20px}
.linkcard .t,.news h3,.keycard h3,.storage h3{font-weight:800;letter-spacing:-.5px}
footer .lockup .name{font-weight:800;letter-spacing:-.5px}

/* ---------- the hand on anything a person touches (settled 22 Sept 2026).
   Amplitude 1.2, a second pass at 62 percent of the stroke and half opacity,
   three frames cycled on hover with steps. Structure stays straight: rules,
   dividers, the index band, the map grid, anything over about 480px, anything
   under 20px. The test is whether a person puts their cursor on it. ---------- */

.drawn{position:relative;background:none;border:0;border-radius:0;padding:13px 24px}
.drawn .ed{position:absolute;inset:0;display:block;pointer-events:none;color:inherit}
.drawn .ed svg{display:block;width:100%;height:100%}
.drawn .t{position:relative}
.drawn .f2,.drawn .f3{opacity:0}
.drawn:hover .f1{animation:bf1 .36s steps(1,end) infinite}
.drawn:hover .f2{animation:bf2 .36s steps(1,end) infinite}
.drawn:hover .f3{animation:bf3 .36s steps(1,end) infinite}
.drawn:active{transform:translateY(2px)}
.drawn:focus-visible{outline:2px solid var(--blue);outline-offset:4px}
@keyframes bf1{0%,33.3%{opacity:1}33.4%,100%{opacity:0}}
@keyframes bf2{0%,33.3%{opacity:0}33.4%,66.6%{opacity:1}66.7%,100%{opacity:0}}
@keyframes bf3{0%,66.6%{opacity:0}66.7%,100%{opacity:1}}

.btn.drawn.btn-primary{color:var(--yellow);background:none;border:0}
.btn.drawn.btn-primary .t{color:var(--field)}
.btn.drawn.btn-ghost{color:#4a4a4a;background:none;border:0}
.btn.drawn.btn-ghost .t{color:var(--ink)}
.topbar nav a.cta.drawn{color:var(--yellow);background:none;padding:9px 15px}
.topbar nav a.cta.drawn .t{color:var(--field)}
.topbar nav a.cta.drawn:hover{filter:none}

.news .field .dfield{position:relative;display:block;flex:0 0 44px;height:44px;width:100%;color:#4a4a4a}
.news .field .dfield .ed{position:absolute;inset:0;pointer-events:none}
.news .field .dfield .ed svg{display:block;width:100%;height:100%}
.news .field .dfield .f2,.news .field .dfield .f3{opacity:0}
.news .field .dfield:focus-within{color:var(--blue)}
.news .field .dfield:focus-within .f1{animation:bf1 .36s steps(1,end) 2}
.news .field .dfield:focus-within .f2{animation:bf2 .36s steps(1,end) 2}
.news .field .dfield:focus-within .f3{animation:bf3 .36s steps(1,end) 2}
.news input{position:relative;background:transparent;border:0;border-radius:0;width:100%;height:44px}
.news input:focus{outline:0}
.news button.drawn{color:var(--yellow);background:none;border:0;padding:0 20px}
.news button.drawn .t{color:var(--field)}
.news button.drawn:hover{filter:none}

/* grain: fractal noise at 5 percent, so the dark fills are not flat. It is a
   filter, not an image, so there is nothing to download or version. */
.grain{position:fixed;inset:0;pointer-events:none;z-index:2;opacity:.05;mix-blend-mode:overlay}
.grain svg{width:100%;height:100%;display:block}

/* ---------- the endorsement block: the one place on a tool page where the
   parent speaks as itself ---------- */
footer .argh{font-family:var(--display);font-weight:800;font-size:34px;letter-spacing:-1.3px;line-height:1;color:var(--ink)}
footer .less{font-family:var(--mono);font-size:10px;letter-spacing:1.5px;color:var(--muted);margin-top:9px}
footer .marks{margin-top:13px;display:flex;gap:12px;align-items:center;opacity:.62}
footer .toolrow{display:flex;align-items:center;gap:10px}
footer .toolrow .n{font-size:13px;color:var(--ash)}
footer .toolrow .s{font-family:var(--mono);font-size:9.5px;letter-spacing:1.1px;color:var(--muted)}

@media (prefers-reduced-motion: reduce){
  .drawn:hover .f1,.drawn:hover .f2,.drawn:hover .f3,
  .news .field .dfield:focus-within .f1,.news .field .dfield:focus-within .f2,.news .field .dfield:focus-within .f3{animation:none}
  .drawn:hover .f1,.news .field .dfield:focus-within .f1{opacity:1}
}

/* ---------- the house page (arghtools.com/). The parent's own surface, so the
   removal test runs the other way: the house is the subject and no single tool
   may dominate. Runs quiet, per the ladder — glazed keys at 7 percent, a motif
   on a few of them at 26. Focused is available in the hero in the week a tool
   ships. It never goes loud: the plate is for print. ---------- */

/* the page grid is Mappr's map paper further out, so the house drops it and
   wears the keycap field instead */
body.house{background-image:none}

.house .topbar .name{font-size:22px}
.house .topbar nav a{font-size:12.5px}

/* the hero fills the screen under the band, so the shelf starts at the fold
   instead of peeking into it (settled 23 Sept 2026) */
.hhero{position:relative;padding:104px 0 96px;overflow:hidden;min-height:calc(100svh - var(--nb));display:flex;align-items:center}
/* the field is an asset, not markup: it keeps index.html small, and it cannot
   paint before the stylesheet that places it, so a slow stylesheet can never
   leave a full-size keycap grid shoving the page around */
.hhero .glaze{
  position:absolute;inset:0;pointer-events:none;
  background:url("hero-field.svg") center center / cover no-repeat;
}
.hhero .wrap{position:relative;width:100%}
.hhero .label{letter-spacing:2.4px}
.hhero h1{
  font-family:var(--display);font-weight:800;
  font-size:104px;line-height:.94;letter-spacing:-4px;
  margin:22px 0 0;
}
.hhero .lead{margin:22px 0 0;max-width:600px;font-size:19px;line-height:1.55;color:var(--ash)}
.hhero .actions{margin-top:34px;display:flex;align-items:center;gap:22px;flex-wrap:wrap}
/* the three promises: straight edges, because they are not buttons, and each
   leads with a motif no tool owns (the rule cards' stamps) */
.claims{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:8px}
.claims li{display:inline-flex;align-items:center;gap:8px;height:30px;padding:0 12px 0 9px;border:1px solid #2f2f2f;background:rgba(18,18,18,.85);
  font-family:var(--mono);font-size:11px;letter-spacing:1.2px;color:var(--ash)}
.claims svg{width:14px;height:14px;flex-shrink:0}

.section.band{background:rgba(20,20,20,.72);border-top:1px solid #232323;border-bottom:1px solid #232323}

/* the index: every tool, equally. Same box, same weight; only the state and
   the link differ, because only one of them exists yet. */
.shelf{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px}
.toolcard{
  background:var(--panel);border:1px solid var(--line);
  border-bottom-width:3px;border-radius:4px;
  padding:26px 28px 24px;display:flex;flex-direction:column;gap:14px;min-height:268px;
}
.toolcard .head{display:flex;align-items:center;gap:12px}
.toolcard h3{font-family:var(--display);font-weight:800;font-size:28px;letter-spacing:-1px;margin:0}
.toolcard .state{margin-left:auto;font-family:var(--mono);font-size:9.5px;letter-spacing:1.3px;color:var(--muted)}
.toolcard .state.on{color:var(--green)}
.toolcard .tline{font-family:var(--mono);font-size:11px;letter-spacing:1.4px;margin:0}
.toolcard p{margin:0;font-size:14px;line-height:1.6;color:var(--ash);flex-grow:1}
.toolcard .go{font-size:14px;font-weight:600}
.toolcard.live{border-bottom-color:var(--yellow)}
.toolcard.live .tline,.toolcard.live .go{color:var(--yellow)}
.toolcard.soon{background:#1a1a1a;border-color:#2b2b2b;border-bottom-color:#2b2b2b}
.toolcard.soon h3{color:var(--muted)}
.toolcard.soon p{color:var(--muted)}
.toolcard.soon svg{opacity:.55}

.houserules{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px}
.houserules .head{display:flex;align-items:baseline;gap:12px;margin-bottom:12px}
.houserules .n{font-family:var(--mono);font-size:11px;color:var(--muted)}
.houserules h3{font-family:var(--display);font-weight:800;font-size:22px;letter-spacing:-.6px;margin:0}
.houserules p{margin:0;font-size:14px;line-height:1.6;color:var(--ash)}

@media (max-width:1000px){
  .hhero{padding:72px 0 64px}
  .hhero h1{font-size:64px;letter-spacing:-2.2px}
  .hhero .lead{font-size:17px}
  .shelf,.houserules{grid-template-columns:minmax(0,1fr)}
  .toolcard{min-height:0}
}
@media (max-width:640px){
  .hhero h1{font-size:46px;letter-spacing:-1.6px}
  .house .topbar nav a{font-size:11.5px}
}

/* ---------- the Open Mappr transition: the house glazing itself over before
   it hands you to the tool. Solid tiles bleeding off every edge, stepped in
   as a wave. Board 06 allows it because a transition is not rest. ---------- */

.glaze-over{
  position:fixed;inset:0;z-index:100;display:grid;
  grid-auto-rows:var(--m);pointer-events:none;
  justify-content:center;align-content:center;
}
.glaze-over .gt{
  display:block;width:var(--m);height:var(--m);opacity:0;
  animation:gtin .001s steps(1,end) forwards;
}
.glaze-over .gt svg{display:block;width:100%;height:100%}
@keyframes gtin{to{opacity:1}}

@media (prefers-reduced-motion: reduce){
  .glaze-over{display:none}
}

/* ---------- the band (book board 14, settled 23 Sept 2026). One row of the
   field, fired, under the bar on every page, in the colours of whoever owns
   the page. tools/build-band.py writes the markup and assets/tiles.svg. It
   fires once on load, left to right; a tile lifts and turns its motif a
   quarter under the cursor. Nothing moves at rest. ---------- */

.tileband{height:68px;overflow:hidden;display:flex;justify-content:center;background:var(--field);position:relative;z-index:1}
.tileband .row{display:flex;flex:0 0 auto}
.tileband .bt{display:block;width:68px;height:68px;flex:0 0 68px;opacity:0;
  animation:bandfire 1ms steps(1,start) forwards;animation-delay:calc(var(--i) * 34ms)}
.tileband .bt svg{display:block;width:100%;height:100%;overflow:visible;transition:transform 90ms steps(2,end)}
.tileband .bt use{transform-box:view-box;transform-origin:60px 60px;transition:transform 120ms steps(2,end)}
@keyframes bandfire{to{opacity:1}}
@media (hover:hover){
  .tileband .bt:hover svg{transform:translateY(-4px)}
  .tileband .bt:hover use{transform:rotate(90deg)}
}
@media (max-width:640px){
  .tileband{height:48px}
  .tileband .bt{width:48px;height:48px;flex-basis:48px}
}

/* ---------- the tool cards are keys (book board 15). A drawn face on a
   skirt in the tool's accent: 3px of skirt at rest, 6px when the cursor is on
   it, 1px when it is pressed. A tool that is not built jams instead of going
   down, and says so. ---------- */

.keycap{position:relative;display:block;width:100%;padding:0 0 6px;margin:0;border:0;background:none;
  font:inherit;text-align:left;color:var(--ink);cursor:pointer;-webkit-appearance:none;appearance:none}
.keycap:hover{color:var(--ink)}
.keycap .skirt{position:absolute;left:0;right:0;top:6px;bottom:0;width:100%;height:calc(100% - 6px);color:var(--acc);display:block}
.keycap.soon .skirt{color:color-mix(in srgb,var(--acc) 26%,#1e1e1e)}
.keycap .face{position:relative;display:block;transform:translateY(3px);transition:transform 80ms steps(2,end)}
.keycap .ed{position:absolute;inset:0;width:100%;height:100%;display:block;color:var(--line);overflow:visible}
.keycap .ed .f2,.keycap .ed .f3,.drawnlink .ed .f2,.drawnlink .ed .f3{opacity:0}
.keycap .in{position:relative;display:flex;flex-direction:column;gap:14px;padding:26px 28px 24px;min-height:262px}
.keycap .head{display:flex;align-items:center;gap:12px}
.keycap .mk{flex-shrink:0;display:block;overflow:visible}
.keycap .h{font-family:var(--display);font-weight:800;font-size:28px;letter-spacing:-1px;line-height:1.1}
.keycap .state{margin-left:auto;font-family:var(--mono);font-size:9.5px;letter-spacing:1.3px;color:var(--muted)}
.keycap .state.on{color:var(--green)}
.keycap .tline{font-family:var(--mono);font-size:11px;letter-spacing:1.4px;text-transform:uppercase;color:var(--yellow)}
.keycap .p{font-size:14px;line-height:1.6;color:var(--ash);flex-grow:1}
.keycap .go{display:flex;align-items:center;gap:8px;height:56px;margin-bottom:-10px}
.keycap .go .t{font-size:14px;font-weight:600;color:var(--yellow);white-space:nowrap}
.keycap .arrow{display:inline-block;transition:transform 80ms steps(2,end)}
.keycap .sprout{width:172px;height:56px;overflow:visible;flex-shrink:0}
.keycap .sprout > g{opacity:0}
.keycap.soon .h,.keycap.soon .p{color:var(--muted)}
.keycap.soon .mk{opacity:.75}
.keycap .ask{font-family:var(--mono);font-size:10.5px;letter-spacing:1.2px;text-transform:uppercase;color:#6f767d}

.keycap:hover .face,.keycap:focus-visible .face{transform:translateY(0)}
.keycap:hover .ed,.keycap:focus-visible .ed{color:var(--acc)}
.keycap:hover .ed .f1,.drawnlink:hover .ed .f1{animation:bf1 .36s steps(1,end) infinite}
.keycap:hover .ed .f2,.drawnlink:hover .ed .f2{animation:bf2 .36s steps(1,end) infinite}
.keycap:hover .ed .f3,.drawnlink:hover .ed .f3{animation:bf3 .36s steps(1,end) infinite}
.keycap:active .face{transform:translateY(5px)}
.keycap:focus-visible{outline:2px solid var(--blue);outline-offset:6px}
.keycap:hover .arrow{transform:translateX(4px)}
/* Mappr: Cmd + arrow, drawn. The branch grows out of Open Mappr. */
@keyframes keyon{to{opacity:1}}
.keycap:hover .sprout .s1{animation:keyon 1ms steps(1,start) 0ms forwards}
.keycap:hover .sprout .s2{animation:keyon 1ms steps(1,start) 150ms forwards}
.keycap:hover .sprout .s3{animation:keyon 1ms steps(1,start) 300ms forwards}
/* Flowr goes round, three quarters. Docr's half disc comes up. */
.keycap .spin > g{transform-box:fill-box;transform-origin:center}
.keycap:hover .spin > g{animation:keyspin .36s steps(3,start) forwards}
@keyframes keyspin{to{transform:rotate(270deg)}}
.keycap .rise{transform:translateY(5px);transition:transform .24s steps(3,end)}
.keycap:hover .rise{transform:translateY(0)}
/* not built: it jams */
.keycap.jam:active .face{transform:translateY(3px);animation:keyjam .18s steps(3,end)}
@keyframes keyjam{0%{transform:translate(0,3px)}33%{transform:translate(-3px,3px)}66%{transform:translate(3px,3px)}100%{transform:translate(0,3px)}}
.kwrap{position:relative}
.kwrap .stuck{position:absolute;left:28px;right:28px;bottom:30px;margin:0;font-size:13.5px;line-height:1.45;color:var(--ash);
  visibility:hidden;pointer-events:none}
.kwrap .stuck a{font-weight:600}
.kwrap:focus-within .stuck,.kwrap.is-stuck .stuck{visibility:visible;pointer-events:auto}
.kwrap:focus-within .ask,.kwrap.is-stuck .ask{visibility:hidden}
@media (hover:none){.keycap .sprout{display:none}}
@media (max-width:1000px){.keycap .in{min-height:0}.keycap.soon .in{min-height:190px}}

/* rule cards are not clickable, so they stay straight and never go down;
   the number is stamped as its tile when you look at it */
.houserules .n{position:relative;display:inline-block;width:26px;height:18px}
.houserules .n .num{position:absolute;left:0;bottom:0}
.houserules .stamp{position:absolute;left:-1px;top:-6px;width:26px;height:26px;visibility:hidden;transform:scale(1.35);transition:transform 90ms steps(2,end)}
.houserules .card:hover .num{visibility:hidden}
.houserules .card:hover .stamp{visibility:visible;transform:scale(1)}

/* link cards: drawn, in their own colour, and each icon has one trick */
.linkcard.drawnlink{position:relative;background:none;border:0;border-radius:0;padding:18px 22px;color:var(--ink)}
.linkcard.drawnlink:hover{background:none}
.linkcard.drawnlink .ed{position:absolute;inset:0;width:100%;height:100%;display:block;overflow:visible;pointer-events:none}
.linkcard.drawnlink > :not(.ed){position:relative}
.linkcard.violet .ed{color:var(--violet)} .linkcard.blue .ed{color:var(--blue)} .linkcard.red .ed{color:var(--red)}
.linkcard.drawnlink:active{transform:translateY(2px)}
.linkcard .arrow{display:inline-block;transition:transform 80ms steps(2,end)}
.linkcard:hover .arrow{transform:translateX(4px)}
.linkcard .dots circle,.linkcard .slash,.linkcard .steam path{opacity:0}
.linkcard:hover .dots circle:nth-child(1),.linkcard:hover .steam path:nth-child(1){animation:keyon 1ms steps(1,start) 0ms forwards}
.linkcard:hover .dots circle:nth-child(2),.linkcard:hover .steam path:nth-child(2),.linkcard:hover .slash{animation:keyon 1ms steps(1,start) 120ms forwards}
.linkcard:hover .dots circle:nth-child(3),.linkcard:hover .steam path:nth-child(3){animation:keyon 1ms steps(1,start) 240ms forwards}
.linkcard .brl,.linkcard .brr{transition:transform 120ms steps(2,end)}
.linkcard:hover .brl{transform:translateX(-2px)}
.linkcard:hover .brr{transform:translateX(2px)}

/* the newsletter card sizes to what is in it, instead of stretching to the
   link column and opening a hole above its footnote */
.community{align-items:start}
.news .foot{margin-top:0}

/* the footer's columns sit at the right edge, as board 13 draws them */
footer .cols{justify-content:flex-end}

/* on a phone the house keeps its three links: they are the only way round it */
@media (max-width:640px){
  .house .topbar nav{gap:14px}
  .house .topbar nav a:not(.cta):not(.argh){display:inline}
}

/* ---------- the plate (book board 16, settled 23 Sept 2026): the tool's glaze
   on an opaque ground, dropped out of the band. mappr-open.js lays it; the app
   rolls it back up. ---------- */
.glaze-over{display:block}
.glaze-over .gt{position:absolute;width:68px;height:68px;animation-timing-function:steps(1,start)}

/* ---------- a phone cannot hover, so a card is selected instead (settled
   23 Sept 2026). keys.js marks the card you tap .is-sel and it shows exactly
   what the cursor would: the edge glazes, the icon does its one trick. A card
   that is a link goes on the second tap, so the trick is seen before it goes.
   Buttons and the nav keys are not cards and act on the first tap. ---------- */
.keycap.is-sel .face{transform:translateY(0)}
.keycap.is-sel:active .face{transform:translateY(5px)}
.keycap.is-sel .ed{color:var(--acc)}
.keycap.is-sel .ed .f1,.drawnlink.is-sel .ed .f1{animation:bf1 .36s steps(1,end) infinite}
.keycap.is-sel .ed .f2,.drawnlink.is-sel .ed .f2{animation:bf2 .36s steps(1,end) infinite}
.keycap.is-sel .ed .f3,.drawnlink.is-sel .ed .f3{animation:bf3 .36s steps(1,end) infinite}
.keycap.is-sel .arrow,.linkcard.is-sel .arrow{transform:translateX(4px)}
.keycap.is-sel .sprout{display:block}
.keycap.is-sel .sprout .s1{animation:keyon 1ms steps(1,start) 0ms forwards}
.keycap.is-sel .sprout .s2{animation:keyon 1ms steps(1,start) 150ms forwards}
.keycap.is-sel .sprout .s3{animation:keyon 1ms steps(1,start) 300ms forwards}
.keycap.is-sel .spin > g{animation:keyspin .36s steps(3,start) forwards}
.keycap.is-sel .rise{transform:translateY(0)}
.houserules .card.is-sel .num{visibility:hidden}
.houserules .card.is-sel .stamp{visibility:visible;transform:scale(1)}
.linkcard.is-sel .dots circle:nth-child(1),.linkcard.is-sel .steam path:nth-child(1){animation:keyon 1ms steps(1,start) 0ms forwards}
.linkcard.is-sel .dots circle:nth-child(2),.linkcard.is-sel .steam path:nth-child(2),.linkcard.is-sel .slash{animation:keyon 1ms steps(1,start) 120ms forwards}
.linkcard.is-sel .dots circle:nth-child(3),.linkcard.is-sel .steam path:nth-child(3){animation:keyon 1ms steps(1,start) 240ms forwards}
.linkcard.is-sel .brl{transform:translateX(-2px)}
.linkcard.is-sel .brr{transform:translateX(2px)}
.houserules .card,.keycap,.linkcard{-webkit-tap-highlight-color:transparent}

@media (prefers-reduced-motion: reduce){
  .tileband .bt{animation:none;opacity:1}
  .keycap:hover .ed .f1,.keycap:hover .ed .f2,.keycap:hover .ed .f3,
  .drawnlink:hover .ed .f1,.drawnlink:hover .ed .f2,.drawnlink:hover .ed .f3,.keycap:hover .spin > g,
  .keycap.is-sel .ed .f1,.keycap.is-sel .ed .f2,.keycap.is-sel .ed .f3,
  .drawnlink.is-sel .ed .f1,.drawnlink.is-sel .ed .f2,.drawnlink.is-sel .ed .f3,.keycap.is-sel .spin > g{animation:none}
  .keycap:hover .ed .f1,.drawnlink:hover .ed .f1,.keycap.is-sel .ed .f1,.drawnlink.is-sel .ed .f1{opacity:1}
}

/* ---------- light the field (book board 17, settled 23 Sept 2026). The keys
   round the cursor show their motif; hero-light.js places and lights them.
   On at once, out after a short stepped linger, never eased. ---------- */
.lightfield{position:absolute;inset:0;pointer-events:none;overflow:hidden}
.lightfield svg{position:absolute;display:block;overflow:visible;opacity:0;transition:opacity 1ms steps(1,end) .26s}
.lightfield svg.l1{opacity:.85;transition-delay:0s}
.lightfield svg.l2{opacity:.42;transition-delay:0s}
.lightfield svg[data-t].l1{opacity:.34}
.lightfield svg[data-t].l2{opacity:.2}

/* ---------- the wave (book board 18, settled 23 Sept 2026). Once the band has
   fired in and sat still for a beat, each motif turns a full circle in eight
   45 degree clicks, left to right, 45ms a tile, then the band settles for
   good. It runs once per load. No fill mode, so when it ends the hover turn
   still works; it ends where it started anyway. Each tile is clipped to its
   own square so a turning glaze never spills onto its neighbours. ---------- */
.tileband .bt svg{clip-path:inset(0)}
.tileband .bt use{animation:bandspin 400ms steps(8,end) calc(1050ms + var(--i) * 45ms)}
@keyframes bandspin{from{transform:rotate(0)}to{transform:rotate(360deg)}}
@media (prefers-reduced-motion: reduce){.tileband .bt use{animation:none}}

/* ---------- the bar in the band (book board 19, settled 23 Sept 2026). The
   page's bar and the band are one sticky row, 56 tall: a tile bleeding off
   the left, the wordmark on the ground, a run of tiles cut off by the keys,
   the links as keys, a tile bleeding off the right. The links are drawn,
   because a person puts their cursor on them (board 05), each an outline in
   its own colour that glazes solid under the cursor, its label going Field as
   text on an accent must. The tiles keep the band's fire, wave and hover. The
   house drops the stripe, since the band carries all six colours; a tool page
   keeps it at 4px as the parent's signature. ---------- */

:root{--nb:56px}
html{scroll-padding-top:var(--nb)}
.spectrum{height:4px}
.navband{position:sticky;top:0;z-index:20;height:var(--nb);display:flex;align-items:stretch;background:var(--field);
  border-bottom:1px solid #1c1c1c}
.navband .tileband{height:var(--nb);display:block;overflow:hidden;background:none}
.navband .tileband .row{display:flex;height:100%}
.navband .tileband .bt{width:var(--nb);height:var(--nb);flex:0 0 var(--nb)}
.navband .nb-lead{flex:0 0 calc(var(--nb) / 2);position:relative}
.navband .nb-lead .row{position:absolute;right:0;top:0}
.navband .nb-tail{flex:0 0 calc(var(--nb) / 2)}
.navband .nb-mid{flex:1 1 0;min-width:0}
.navband .nb-brand{flex:0 0 auto;display:flex;align-items:center;gap:12px;padding:0 28px 0 18px}
.navband .nb-word{display:flex;align-items:center;gap:11px;font-family:var(--display);font-weight:800;
  font-size:22px;letter-spacing:-.8px;color:var(--ink);text-decoration:none}
.navband .nb-word:hover{color:var(--ink)}
.navband .ver{font-family:var(--mono);font-size:10px;color:var(--muted);border:1px solid var(--line);padding:2px 6px;border-radius:3px}
.navband .nb-keys{flex:0 0 auto;display:flex}

.nkey{position:relative;display:flex;align-items:center;justify-content:center;min-width:112px;height:var(--nb);
  padding:0 22px;box-sizing:border-box;text-decoration:none;font-family:var(--mono);font-size:12.5px;font-weight:600;
  color:var(--acc)}
.nkey:hover{color:var(--acc)}
.nkey .ed,.nkey .fl{position:absolute;inset:0;width:100%;height:100%;display:block;overflow:visible;pointer-events:none;color:var(--acc)}
.nkey .fl{opacity:0}
.nkey .ed .f2,.nkey .ed .f3{opacity:0}
.nkey .t{position:relative;white-space:nowrap}
.nkey .short{display:none}
.nkey:hover .fl,.nkey:focus-visible .fl,.nkey[data-solid] .fl{opacity:1}
.nkey:hover .t,.nkey:focus-visible .t,.nkey[data-solid] .t{color:var(--field)}
.nkey:hover .ed .f1{animation:bf1 .36s steps(1,end) infinite}
.nkey:hover .ed .f2{animation:bf2 .36s steps(1,end) infinite}
.nkey:hover .ed .f3{animation:bf3 .36s steps(1,end) infinite}
.nkey:active{transform:translateY(2px)}
.nkey:focus-visible{outline:2px solid var(--blue);outline-offset:-5px}

@media (max-width:760px){
  :root{--nb:48px}
  .navband .nb-mid{display:none}
  .navband .nb-brand{flex:1 1 auto;padding:0 10px}
  .navband .nb-word{font-size:19px}
  .navband .ver{display:none}
  .nkey{min-width:0;padding:0 12px;font-size:11.5px}
  .nkey .long{display:none}
  .nkey .short{display:inline}
  .nkey[data-wide]{display:none}
}
@media (max-width:380px){
  .navband .nb-lead,.navband .nb-tail{display:none}
}
@media (prefers-reduced-motion: reduce){
  .nkey:hover .ed .f1,.nkey:hover .ed .f2,.nkey:hover .ed .f3{animation:none}
  .nkey:hover .ed .f1{opacity:1}
}

/* ---------- the bar in the band, tightened (book board 20, settled 23 Sept
   2026). The wordmark sits on the band: 14px either side of it, and the tile
   beside it is always solid. No rainbow stripe on any page. The run of tiles
   is a whole number of tiles wide, so no tile is ever cut against a key, and
   the few pixels left over go to the keys, which stretch to take them
   (navband.js measures it; without JS the leftover is a small gap before the
   keys, never a cut tile). On a phone the half tiles at the edges go and the
   run stays. ---------- */
.spectrum{display:none}
.navband .nb-brand{padding:0 14px 0 16px}
.navband .nb-mid .row{flex-wrap:wrap;align-content:flex-start}
.navband .nkey{flex:1 0 auto}
.navband.fitted .nb-mid{flex:0 0 auto}
.navband.fitted .nb-keys{flex:1 0 auto}
@media (max-width:760px){
  .navband .nb-mid{display:block}
  .navband .nb-lead,.navband .nb-tail{display:none}
  .navband .nb-brand{flex:0 0 auto;padding:0 10px 0 14px}
}
