/* Ookii Tag
   One background canvas, assets/canvas.webp, 1161 x 1355, with live HTML on
   top. Every coordinate below was measured off that file, not estimated.

   Panels measured, as percentages of the canvas:
     white builder sheet   x  5.50-51.46   y 11.36-63.07
     black output panel    x 53.17-94.20   y 11.39-59.79
     batch strip           x  6.75-95.67   y 63.11-76.14
     naming sheet          x  5.83-96.38   y 77.11-98.36
     naming cards          y 82.29-97.70, rule at 82.29-82.79
       card 1  x 10.04-28.67    card 2  x 31.25-48.58
       card 3  x 52.75-70.25    card 4  x 73.62-91.12
   Painted swatches:
     build   x  9.12-21.92  y 13.86-16.79   (black)
     options x 10.79-21.46  y 48.75-51.25   (black)
     output  x 55.21-70.21  y 13.25-16.82   (teal)
     sets    x 55.38-68.58  y 27.96-31.43   (orange)
     recent  x 55.21-67.25  y 40.04-42.89   (teal)
     batch   x  9.75-21.62  y 64.86-67.36   (orange)
   The naming heading has no painted swatch in the artwork, so it is drawn.

   Type inside .layer is in cqw, which scales with the canvas. Below 1100px
   the canvas is dropped entirely for a stacked layout. */

@font-face {
  font-family: "Anton";
  src: url("assets/fonts/anton-latin.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Permanent Marker";
  src: url("assets/fonts/marker-latin.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Outfit";
  src: url("assets/fonts/outfit-var-latin.woff2") format("woff2-variations");
  font-weight: 100 900; font-style: normal; font-display: swap;
}

:root{
  --paper:#ede6e1;
  --paper-2:#ebe3de;
  --ink:#090909;
  --wall:#031518;
  --wall-2:#02191d;
  --teal:#007486;
  --teal-lift:#33a6b6;
  --orange:#e65301;
  --chalk:#f4f1ec;
  --hand:"Permanent Marker","Segoe Print","Bradley Hand",cursive;
  --sans:"Outfit",Arial,Helvetica,sans-serif;
  --display:"Anton",Impact,"Arial Black",sans-serif;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;min-width:320px;color:var(--chalk);font-family:var(--sans);
  line-height:1.45;overflow-x:hidden;background:var(--wall)
    url("assets/wall-tile.webp") repeat 0 0;background-size:700px 700px}
a{color:inherit}
button,input,textarea{font:inherit;color:inherit}
button{cursor:pointer}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.skip-link{position:absolute;left:-9999px}
.skip-link:focus{left:12px;top:12px;z-index:1000;background:var(--chalk);color:var(--ink);
  padding:11px 15px;font-weight:600}

/* ---------- Page heading ----------
   The artwork carries this above 1100px, so it is clipped there rather than
   removed: the document still needs one h1 for search and screen readers. */
.mhero{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);
  white-space:nowrap}

/* ---------- Canvas ---------- */
.stage{position:relative;width:100%;container-type:inline-size}
.canvas{display:block;width:100%;height:auto}
.layer{position:absolute;inset:0}
.layer > *{position:absolute;margin:0}

.hero-support{position:absolute;left:62.2%;top:5.9%;width:9.8%;height:3.6%;
  display:flex;align-items:center;justify-content:center;text-decoration:none;
  background:var(--orange);color:#1a0a00;font-family:var(--hand);text-transform:uppercase;
  font-size:.8cqw;letter-spacing:.03em;text-align:center;line-height:1.1;padding:0 .4cqw;
  clip-path:polygon(1% 7%,99% 0,100% 93%,0 100%);z-index:2}
.hero-support:hover{filter:brightness(1.12)}
.hero-support:focus-visible{outline:3px solid var(--chalk);outline-offset:3px}

/* ---------- Painted headings ----------
   The words go here in live markup rather than baked into the artwork, so
   they read to a screen reader and can be changed without a re-render. */
.brush{font-family:var(--hand);font-weight:400;text-transform:uppercase;
  letter-spacing:.02em;line-height:1;display:flex;align-items:center;
  padding-left:.7cqw;white-space:nowrap}
.brush--build   {left: 9.12%;top:13.86%;width:12.80%;height:2.93%;font-size:1.15cqw;color:var(--chalk)}
.brush--quick   {left:10.79%;top:48.75%;width:10.67%;height:2.50%;font-size:1.05cqw;color:var(--chalk)}
.brush--out     {left:55.21%;top:13.25%;width:15.00%;height:3.57%;font-size:1.15cqw;color:var(--chalk)}
.brush--break   {left:55.38%;top:27.96%;width:13.20%;height:3.47%;font-size:1.05cqw;color:#1a0a00}
/* No painted swatch is free for this one, so it is drawn to match. */
.brush--sets    {left:55.38%;top:52.20%;width:14%;height:2.2%;font-size:.95cqw;color:var(--chalk);
  background:var(--teal);transform:rotate(-.4deg);clip-path:polygon(0 12%,97% 0,100% 84%,3% 100%)}
.brush--recent  {left:55.21%;top:40.04%;width:12.04%;height:2.85%;font-size:1.05cqw;color:var(--chalk)}
.brush--batch   {left: 9.75%;top:64.86%;width:11.87%;height:2.50%;font-size:1.05cqw;color:#1a0a00}
/* No painted swatch exists for this one, so it is drawn to match the others. */
.brush--naming  {left: 9.60%;top:78.30%;width:19%;height:2.7%;font-size:1.15cqw;color:var(--chalk);
  background:var(--teal);transform:rotate(-.5deg);
  clip-path:polygon(0 12%,97% 0,100% 82%,3% 100%)}

/* ---------- Shared field furniture ---------- */
.fld > *{position:static}
.fld label{display:block;font-size:.95cqw;font-weight:700;color:#1c1c1a;margin-bottom:.4cqw}
.req{font-weight:600;color:#b8390a;font-size:.85cqw;margin-left:.3cqw}
.fld input{width:100%;height:2.4%;min-height:38px;padding:0 .8cqw;font-size:1cqw;
  color:#20211f;background:rgba(255,255,255,.55);border:1px solid rgba(28,28,26,.34);
  border-radius:2px;outline:none}
.fld input::placeholder{color:#8b8b86}
.fld input:focus{border-color:var(--teal);box-shadow:0 0 0 3px rgba(0,116,134,.22)}
.help{margin:.4cqw 0 0;font-size:.82cqw;line-height:1.4;color:#3a3b38}

.btn{border:0;border-radius:2px;font-family:var(--hand);text-transform:uppercase;
  letter-spacing:.03em;font-size:.95cqw;display:inline-flex;align-items:center;
  justify-content:center;gap:.5cqw;padding:0 1cqw;min-height:36px;
  clip-path:polygon(1% 6%,99% 0,100% 92%,0 100%)}
.btn--dark{background:#111;color:var(--chalk)}
.btn--teal{background:var(--teal);color:#fff}
.btn--orange{background:var(--orange);color:#1a0a00}
.btn:disabled{opacity:.4;cursor:not-allowed}
.btn:hover:not(:disabled){filter:brightness(1.12)}
.btn:focus-visible,.seg:focus-visible,.fld input:focus-visible,
.setin:focus-visible,#t-batch:focus-visible,.clear-inline:focus-visible,
.brush summary:focus-visible,.footer-copy:focus-visible,
.site-footer a:focus-visible,.pick input:focus-visible{outline:3px solid var(--teal-lift);outline-offset:2px}

/* ---------- Builder fields ---------- */
/* Fields and options both sit above the painted swatch at 48.75%, which now
   heads Quick start instead of Options. The budget is tight: the field help
   had to come down to two lines and the strip row lost its help line. */
.fld-base    {left: 9.13%;top:18.40%;width:38.5%}
.fld-source  {left: 9.13%;top:24.50%;width:11.9%}
.fld-medium  {left:22.60%;top:24.50%;width:11.9%}
.fld-campaign{left:36.10%;top:24.50%;width:11.9%}
.fld-term    {left: 9.13%;top:31.60%;width:11.9%}
.fld-content {left:22.60%;top:31.60%;width:11.9%}
.fld-id      {left:36.10%;top:31.60%;width:11.9%}

.opt{border:0;padding:0;margin:0}
.opt > *{position:static}
.opt legend{padding:0;font-size:.82cqw;font-weight:700;color:#1c1c1a}
.pick{display:inline-flex;align-items:center;gap:.45cqw;font-size:.82cqw;color:#262624;
  cursor:pointer;margin-right:1.4cqw}
.pick input{appearance:none;-webkit-appearance:none;margin:0;width:1cqw;height:1cqw;
  min-width:14px;min-height:14px;border:2px solid #4a4a46;border-radius:50%;
  background:#fff;cursor:pointer}
.pick input[type=checkbox]{border-radius:2px}
.pick input:checked{background:var(--teal);border-color:var(--teal);box-shadow:inset 0 0 0 2px #fff}
.pick--check{align-items:flex-start;margin-right:0}
.pick--check span{max-width:34cqw}
.opt-head{left:9.13%;top:38.80%;font-size:.95cqw;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:#1c1c1a;font-family:var(--sans)}
.opt-case{left:9.13%;top:40.40%;width:38.5%;display:flex;align-items:center;gap:1cqw}
.opt-sep{left:9.13%;top:42.80%;width:38.5%;display:flex;align-items:center;gap:1cqw}
.opt legend{float:left;margin-right:.6cqw;white-space:nowrap}
.segs{display:flex;gap:.5cqw;flex-wrap:wrap}
.seg{border:1px solid rgba(28,28,26,.4);background:rgba(255,255,255,.5);color:#262624;
  border-radius:2px;padding:.35cqw .6cqw;font-size:.78cqw;white-space:nowrap}
.seg.is-on{background:var(--teal);border-color:var(--teal);color:#fff}
.opt-strip{left:9.13%;top:45.20%;width:38.5%}
/* These sat at 66.3%, which is past the panel's bottom edge at 63.07%, so
   they were rendering on the batch strip below. */
.presets-note{left:23.20%;top:49.10%;width:23%;font-size:.8cqw;line-height:1.35;color:#3a3b38}
.presets{left:9.13%;top:52.20%;width:38.5%;display:flex;gap:.7cqw}
.preset{flex:1;border:1px solid rgba(28,28,26,.4);background:rgba(255,255,255,.5);
  color:#1c1c1a;border-radius:2px;padding:.5cqw .3cqw;font-size:.85cqw;font-weight:600;
  min-height:36px;line-height:1.2}
.preset:hover{background:var(--teal);border-color:var(--teal);color:#fff}
.preset:focus-visible{outline:3px solid var(--teal);outline-offset:2px}

.btn-reset{left: 9.13%;top:56.40%;width:10%;height:2.5%}
.btn-build{left:22.00%;top:56.40%;width:13%;height:2.5%}

/* ---------- Output panel ---------- */
.url-out{left:55.38%;top:18.10%;width:24.5%;height:5.3%;min-height:52px;
  padding:.7cqw .8cqw;overflow:auto;font-size:.88cqw;line-height:1.5;
  color:#dfe3e1;background:rgba(255,255,255,.05);
  border:1px solid rgba(255,255,255,.22);border-radius:2px;word-break:break-all}
.u-empty{color:#8e9793}
.u-tag{color:var(--teal-lift)}
.btn-copy{left:81.20%;top:18.10%;width:12.5%;height:5.3%}
.help--out{left:55.38%;top:24.10%;width:30%;color:#a9b0ad;font-size:.82cqw}

.breakdown{left:55.38%;top:32.20%;width:38.4%;height:7.2%;overflow:auto}
.breakdown > *{position:static}
.chips{display:flex;flex-wrap:wrap;gap:.5cqw}
.chip{display:inline-flex;max-width:100%;border:1px solid rgba(255,255,255,.2);
  background:rgba(255,255,255,.04);font-size:.8cqw;border-radius:2px}
.chip__k{padding:.25cqw .45cqw;background:rgba(0,116,134,.35);color:#8fdfe8;text-transform:uppercase}
.chip__v{padding:.25cqw .5cqw;overflow-wrap:anywhere}
.chip--base .chip__k{background:rgba(230,83,1,.35);color:#ffc09a}
.chip--ghost{opacity:.62}
.flags{margin-top:.6cqw}
.flag{margin:.4cqw 0 0;padding-left:.6cqw;border-left:3px solid #6d7674;
  color:#cdd2cf;font-size:.82cqw}
.flag--warn{border-color:var(--orange)}
.flag--stop{border-color:#e04a35;color:#ffd3cb}

/* ---------- Saved sets ---------- */
.setlbl{left:55.38%;top:55.30%;font-size:.85cqw;font-weight:600;color:#d6dbd8}
.setin{left:63.20%;top:54.90%;width:20.5%;height:2.5%;min-height:36px;padding:0 .8cqw;
  font-size:.85cqw;color:#e8ece9;background:rgba(255,255,255,.05);
  border:1px solid rgba(255,255,255,.24);border-radius:2px;outline:none}
.setin::placeholder{color:#7f8785}
.btn-save{left:85.00%;top:54.90%;width:8.7%;height:2.5%}
.empty{color:#9aa29e;font-size:.78cqw}
.empty--sets{left:55.38%;top:58.00%;width:35%}
.setlist{left:55.38%;top:57.70%;width:38.4%;height:2.0%;list-style:none;padding:0;margin:0;
  overflow:auto}
.saved-set{display:flex;justify-content:space-between;gap:.6cqw;align-items:baseline;
  padding:.25cqw 0;border-bottom:1px solid rgba(255,255,255,.12);font-size:.78cqw}
.saved-set__meta{color:#98a09c;font-size:.72cqw;overflow-wrap:anywhere}

/* ---------- Recent values ---------- */
.clear-inline{left:86.50%;top:40.70%;border:0;background:transparent;color:#cfd4d1;
  font-family:var(--hand);text-transform:uppercase;font-size:.8cqw;padding:.3cqw 0}
.recent-grid{left:55.38%;top:43.80%;width:38.4%;height:7.6%;display:grid;
  grid-template-columns:repeat(5,minmax(0,1fr));gap:.5cqw;overflow:auto}
.recent-col h3{margin:0 0 .3cqw;font-size:.78cqw;color:var(--teal-lift);
  text-transform:uppercase;letter-spacing:.03em}
.recent-col button{display:block;width:100%;text-align:left;border:0;background:transparent;
  color:#dfe3e1;font-size:.75cqw;padding:.12cqw 0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.recent-col button:hover{color:var(--teal-lift);text-decoration:underline}
.recent-col .recent-placeholder{color:#9aa29e;font-size:.75cqw}

/* ---------- Copied links, below the canvas ----------
   This list grows every time someone copies, so nothing painted can hold it. */
.copied{margin-top:26px;padding-top:20px;border-top:1px solid rgba(255,255,255,.14)}
.copied h2{margin:0 0 12px;font-family:var(--hand);font-weight:400;text-transform:uppercase;
  font-size:19px;letter-spacing:.03em;color:var(--chalk);display:flex;align-items:center;gap:10px}
.count{background:rgba(0,116,134,.45);color:#bdeef4;border-radius:2px;padding:2px 9px;
  font-family:var(--sans);font-size:13px}
.rec-list{list-style:none;padding:0;margin:0}
.recent__item{padding:12px 0;border-bottom:1px solid rgba(255,255,255,.12)}
.recent__item:last-child{border-bottom:0}
.recent__url{font-family:Consolas,ui-monospace,monospace;font-size:13px;
  color:#d6dad6;overflow-wrap:anywhere}
.recent__meta{display:flex;flex-wrap:wrap;gap:16px;margin-top:7px;align-items:center;
  color:#98a09c;font-size:13px}
.link{border:0;background:transparent;padding:5px 0;min-height:30px;color:var(--teal-lift);
  text-transform:uppercase;font-size:13px}
.link:hover{text-decoration:underline}

/* ---------- Batch strip ---------- */
.protip{left:23.50%;top:65.40%;width:40%;font-size:.85cqw;color:#c6cbc8}
.protip b{color:var(--orange);text-transform:uppercase;font-family:var(--hand);
  font-weight:400;margin-right:.4cqw}
.batch-note{left:9.75%;top:68.20%;width:70%;font-size:.85cqw;color:#b9bfbc}
#t-batch{left:9.75%;top:70.00%;width:84%;height:3.9%;padding:.5cqw .7cqw;resize:none;
  font-family:Consolas,ui-monospace,monospace;font-size:.78cqw;line-height:1.5;
  color:#dfe3e1;background:rgba(255,255,255,.05);
  border:1px solid rgba(255,255,255,.22);border-radius:2px;outline:none}
#t-batch::placeholder{color:#7f8785}
/* A stacked column overflowed the strip, which ends at 76.14%. A row fits. */
.batch-actions{left:9.75%;top:74.20%;width:84%;height:1.9%;display:flex;gap:.8cqw}
.batch-actions .btn{flex:1;min-height:0;height:100%;font-size:.88cqw}

/* ---------- Naming cards ---------- */
.ncard{top:83.90%;height:13.2%;padding:0 1.3cqw;color:#252623;overflow:hidden}
.ncard > *{position:static}
.ncard h3{margin:0 0 .7cqw;font-family:var(--hand);font-weight:400;text-transform:uppercase;
  font-size:1.32cqw;letter-spacing:.02em;color:#141513}
.ncard p{margin:0 0 .6cqw;font-size:1.02cqw;line-height:1.45}
.ncard .eg{color:#55574f}
.nc1{left:10.04%;width:18.63%}
.nc2{left:31.25%;width:17.33%}
.nc3{left:52.75%;width:17.50%}
.nc4{left:73.62%;width:17.50%}

/* ---------- Below the canvas ---------- */
.results{max-width:1240px;margin:0 auto;padding:0 20px}
.batch-out{background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.16);
  border-radius:4px;padding:16px;margin-top:26px}
.batch-out:empty{display:none}
.batch__row{display:grid;grid-template-columns:34px minmax(0,1fr) auto;gap:12px;
  align-items:start;border-top:1px dashed rgba(255,255,255,.15);padding:10px 0;font-size:13px}
.batch__row:first-child{border-top:0}
.batch__row button{border:0;background:transparent;color:var(--teal-lift);font-size:13px;
  text-transform:uppercase;padding:4px 0;min-height:30px}
.batch-out .flag{font-size:14px}

.site-footer{max-width:1240px;margin:0 auto;padding:34px 20px 40px;display:flex;
  flex-wrap:wrap;gap:16px 28px;align-items:center;justify-content:space-between;
  font-size:13px;color:#b6bcb9;border-top:1px solid rgba(255,255,255,.12);margin-top:30px}
.site-footer p{margin:0}
.site-footer nav{display:flex;flex-wrap:wrap;gap:20px}
.site-footer a{text-decoration:none;font-weight:600}
.footer-support{background:var(--orange);color:#1a0a00;padding:11px 20px;border-radius:2px;
  font-family:var(--hand);text-transform:uppercase;letter-spacing:.03em;font-size:15px;
  clip-path:polygon(1% 6%,99% 0,100% 94%,0 100%)}
.footer-support:hover{filter:brightness(1.12);text-decoration:none;color:#1a0a00}
.site-footer a:hover{text-decoration:underline;color:var(--chalk)}

.toast{position:fixed;left:50%;bottom:18px;transform:translateX(-50%);background:#0d1a1c;
  border:1px solid var(--teal);color:var(--chalk);padding:12px 18px;border-radius:3px;
  opacity:0;pointer-events:none;transition:opacity .2s ease,transform .2s ease;
  font-size:14px;z-index:60}
.toast.is-on,.toast.is-up{opacity:1;transform:translateX(-50%) translateY(-5px)}
.toast.is-bad{border-color:#e04a35}

/* ---------- Below 1100px the canvas is dropped ----------
   The artwork is a fixed composition. Squeezing it onto a phone means
   unreadable type, so everything falls back to stacked layout on the wall
   colour with full size controls. */
@media (max-width:1100px){
  .canvas{display:none}

  /* Tighter tile on narrow screens so the brickwork keeps its scale, with a
     soft colour wash over it for depth. */
  body{background-size:340px 340px}
  body::before{content:"";position:fixed;inset:0;pointer-events:none;z-index:0;
    background:
      radial-gradient(120% 55% at 6% 0%, rgba(0,139,143,.14) 0%, transparent 60%),
      radial-gradient(110% 45% at 98% 34%, rgba(230,83,1,.10) 0%, transparent 62%),
      linear-gradient(180deg, rgba(2,10,12,.55) 0%, rgba(2,10,12,.18) 34%, rgba(2,10,12,.6) 100%)}
  .mhero,.stage,.results,.site-footer{position:relative;z-index:1}

  .mhero{position:relative;width:auto;height:auto;overflow:hidden;clip-path:none;
    white-space:normal;margin:0;padding:36px 20px 34px;
    background:url("assets/mobile-hero.webp") no-repeat right center/cover}
  /* Same three effects as the desktop hero, scoped to the mobile artwork.
     The drips run down the right, alongside the ones already painted there. */
  .mhero-fx{display:block;position:absolute;inset:0;max-width:none;z-index:1;
    overflow:hidden;pointer-events:none}
  .mhero-fx .drip{width:3px}
  .mhero-fx .torch{width:52%;animation-duration:14s}
  .mhero-fx .grain{opacity:.2}
  .d4{left:58%;top:2%;height:34%;animation:drip 12s ease-in-out 2.2s infinite}
  .d5{left:72%;top:2%;height:52%;animation:drip 15s ease-in-out 5.1s infinite}
  .d6{left:83%;top:2%;height:26%;animation:drip 13s ease-in-out 8.3s infinite}
  .d7{left:92%;top:2%;height:44%;animation:drip 17s ease-in-out 11s infinite}
  .mhero::after{content:"";position:absolute;inset:0;pointer-events:none;
    background:linear-gradient(100deg, rgba(3,10,12,.86) 0%, rgba(3,10,12,.62) 46%,
      rgba(3,10,12,.12) 78%, transparent 100%)}
  .mhero > *:not(.mhero-fx){position:relative;z-index:2;max-width:min(430px,72%)}
  .mhero__brand{margin:0 0 14px;font-family:var(--hand);text-transform:uppercase;
    letter-spacing:.06em;font-size:14px;color:var(--teal-lift)}
  .mhero__title{margin:0;font-family:var(--display);text-transform:uppercase;
    font-size:clamp(52px,17vw,88px);line-height:.92;letter-spacing:.01em;
    font-weight:400;color:var(--chalk)}
  .mhero__title span{color:var(--teal-lift)}
  .mhero__tagline{margin:10px 0 0;font-family:var(--hand);text-transform:uppercase;
    font-size:16px;letter-spacing:.02em;color:#c6cbc8}
  .mhero__promise{list-style:none;display:flex;flex-wrap:wrap;gap:6px 14px;
    margin:20px 0 0;padding:0;font-family:var(--hand);text-transform:uppercase;
    font-size:15px;color:var(--chalk)}
  .mhero__private{margin:18px 0 0;padding:14px 16px;font-size:14px;line-height:1.45;
    color:#1c1c1a;background:var(--paper);
    clip-path:polygon(0 6%,100% 0,99% 94%,1% 100%);transform:rotate(-.6deg)}
  .mhero__private b{font-weight:700}
  .mhero__support{display:inline-block;width:auto;max-width:none;margin:20px 0 0;padding:14px 22px;
    animation-delay:1.1s, 2.5s;
    background:var(--orange);color:#1a0a00;text-decoration:none;border-radius:3px;
    font-family:var(--hand);text-transform:uppercase;letter-spacing:.03em;font-size:16px}
  .mhero__support:hover{filter:brightness(1.12)}
  .stage,.results{container-type:normal;max-width:680px;margin:0 auto;padding:0}
  /* The form sat straight on the brickwork, which made labels and
     placeholders hard to read. One panel behind the whole stack fixes it
     without wrappers that would break the desktop positioning. */
  .layer,.results{position:relative;background:#080a0a;
    border-top:3px solid var(--teal);border-bottom:1px solid rgba(255,255,255,.1)}
  .layer::before,.results::before{content:"";position:absolute;inset:0;pointer-events:none;
    opacity:.5;mix-blend-mode:overlay;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='150' height='150'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23p)'/%3E%3C/svg%3E")}
  .layer > *,.results > *{position:relative;z-index:1}
  .layer{display:grid;gap:22px;padding:30px 20px 34px}
  .results{border-top-color:var(--orange);margin-top:22px;padding:26px 20px 30px}
  .layer > *{position:static;width:auto!important;height:auto!important;
    transform:none!important;clip-path:none!important}

  .brush{display:inline-block;padding:8px 14px;font-size:19px;color:#fff;
    white-space:normal;background:#111;width:auto!important;justify-self:start}
  .brush--out,.brush--recent,.brush--naming,.brush--sets{background:var(--teal)}
  .brush--break,.brush--batch{background:var(--orange);color:#1a0a00}

  .fld label{color:var(--chalk);font-size:14px;margin-bottom:6px}
  .req{font-size:13px;color:#ff8a5c}
  .fld input,.setin,#t-batch{width:100%;min-height:46px;padding:12px;font-size:17px;
    color:var(--chalk);background:rgba(255,255,255,.06);
    border:1px solid rgba(255,255,255,.28);border-radius:3px}
  #t-batch{min-height:150px;resize:vertical}
  .help{font-size:13px;color:#aab0ad;margin-top:6px}
  .opt legend,.pick,.seg,.setlbl{font-size:15px;color:var(--chalk)}
  .opt-head{font-size:19px;font-weight:500;color:var(--chalk);margin-top:14px;
    padding-top:16px;border-top:2px solid rgba(255,255,255,.16);letter-spacing:.04em;
    font-family:var(--hand);text-transform:uppercase}
  .presets{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
  .preset{min-height:48px;font-size:15px;background:rgba(255,255,255,.06);
    border-color:rgba(255,255,255,.28);color:var(--chalk);border-radius:3px}
  .presets-note{font-size:14px;color:#aab0ad}

  /* Container query units have no container below 1100px, so every cqw value
     left unhandled resolves against the viewport instead. On a 390px phone
     .88cqw is about 3px. Every one of these is a real size here. */
  .batch-actions{gap:12px}
  .batch-actions .btn{font-size:17px;min-height:48px;height:auto;padding:14px}
  .brush{padding-left:14px}
  .brush--sets,.brush--naming{font-size:19px}
  .pick--check span{max-width:none}
  .segs{gap:10px}
  .url-out{font-size:15px;padding:14px}
  .help--out{font-size:13px}
  .chips{gap:8px}
  .flags{margin-top:10px}
  .flag{padding-left:10px}
  .setlbl{font-size:15px}
  .clear-inline{font-size:15px;padding:6px 0}
  .protip{font-size:14px}
  .protip b{margin-right:8px}
  .ncard{padding:18px}
  .chip__k,.chip__v{padding:5px 9px}
  .breakdown{height:auto}
  .recent-grid,.rec-list,.setlist,.copied{height:auto}
  .hero-fx{display:none}
  /* This one belongs to the canvas hero, which is hidden here. The header
     carries its own support button, so showing both duplicates it. */
  .hero-support{display:none}
  .footer-support{font-size:16px;padding:13px 22px}
  .opt legend{float:none;margin-right:0}
  .opt-case,.opt-sep{display:flex;flex-wrap:wrap;gap:14px;align-items:center}
  .pick input{width:22px;height:22px}
  .seg{padding:10px 15px;font-size:14px;background:rgba(255,255,255,.06);
    border-color:rgba(255,255,255,.28);color:var(--chalk)}
  .seg.is-on{background:var(--teal);color:#fff}
  .btn{width:100%;min-height:48px;font-size:17px;padding:12px}
  .btn-reset,.btn-build,.btn-copy,.btn-save{width:100%}
  .batch-actions{display:grid;gap:12px}

  .url-out{min-height:80px;padding:14px;font-size:15px}
  .chip,.chip__k,.chip__v,.flag{font-size:13px}
  .recent-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;overflow:visible}
  .recent-col h3,.recent-col button,.recent-col .recent-placeholder{font-size:14px}
  .recent-col button{padding:8px 0;min-height:34px;white-space:normal}
  .breakdown{overflow:visible}
  .saved-set,.saved-set__meta,.empty{font-size:13px}
  .clear-inline{font-size:15px;justify-self:start}
  .protip,.batch-note{font-size:14px;color:#c2c8c5}
  .ncard{background:rgba(237,230,225,.94);border-radius:0;padding:18px;overflow:visible;
    border-top:5px solid var(--teal)}
  .nc2,.nc4{border-top-color:var(--orange)}
  .ncard h3{font-size:19px}
  .ncard p{font-size:15px}
  .site-footer{margin-top:24px}
}
/* ---------- Hero effects ----------
   All three sit in the hero band only, above the canvas and below the live
   controls, and none of them intercepts a click. They loop slowly and at low
   contrast on purpose: this runs the whole time somebody is filling in a six
   field form, so anything faster or brighter makes the form harder to use. */
.hero-fx{position:absolute;left:0;top:0;right:0;height:11.36%;
  overflow:hidden;pointer-events:none;z-index:1}
.hero-fx i,.mhero-fx i{position:absolute;display:block}
.mhero-fx{display:none}

/* 1. Torch sweep. A soft band of light drifts across the wall on a slow loop,
      as if somebody walked past with a torch. */
.torch{top:-40%;left:0;width:34%;height:180%;
  background:linear-gradient(100deg,transparent 0%,rgba(255,255,255,.055) 42%,
    rgba(0,139,143,.05) 56%,transparent 100%);
  transform:translateX(-120%) skewX(-14deg);
  animation:torch 17s cubic-bezier(.45,0,.55,1) 1.4s infinite}
@keyframes torch{
  0%{transform:translateX(-120%) skewX(-14deg)}
  55%,100%{transform:translateX(430%) skewX(-14deg)}
}

/* 2. Paint drips. Three teal lines run down the clear wall to the right of
      the wordmark, hold, then fade and start again at different speeds. */
.drip{width:2px;top:2.4%;transform-origin:top center;background:linear-gradient(
  180deg,rgba(0,139,143,.85) 0%,rgba(0,139,143,.55) 70%,rgba(0,139,143,0) 100%)}
.drip::after{content:"";position:absolute;left:-2px;bottom:-3px;width:6px;height:6px;
  border-radius:50%;background:rgba(0,139,143,.7)}
.d1{left:38.2%;height:52%;animation:drip 11s ease-in-out 1.8s infinite}
.d2{left:41.6%;height:74%;animation:drip 14s ease-in-out 4.6s infinite}
.d3{left:44.3%;height:38%;animation:drip 13s ease-in-out 8.2s infinite}
@keyframes drip{
  0%{transform:scaleY(0);opacity:0}
  8%{opacity:.9}
  46%{transform:scaleY(1);opacity:.9}
  70%{transform:scaleY(1);opacity:0}
  100%{transform:scaleY(1);opacity:0}
}

/* 3. Grain shimmer. The wall texture drifts a few pixels so the concrete
      never sits perfectly still. */
.grain{inset:0;opacity:.16;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:160px 160px;
  animation:grain 9s steps(6,end) infinite}
@keyframes grain{
  0%{background-position:0 0}
  100%{background-position:160px 160px}
}

/* ---------- Movement ----------
   The canvas settles in, then the painted headings come up one after another,
   so the page assembles rather than appearing all at once. */
@keyframes settle{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes tagUp{from{opacity:0;transform:translateY(14px) rotate(-1.2deg)}to{opacity:1;transform:none}}
.canvas{animation:settle .5s ease-out both}
.brush{animation:tagUp .45s ease-out both}
.brush--build {animation-delay:.18s}
.brush--out   {animation-delay:.26s}
.brush--break {animation-delay:.34s}
.brush--recent{animation-delay:.42s}
.brush--sets  {animation-delay:.46s}
.brush--quick {animation-delay:.50s}
.brush--batch {animation-delay:.58s}
.brush--naming{animation-delay:.66s}
/* ---------- Support buttons ----------
   These need to catch the eye on arrival, so they get a slap-on entrance, then
   three nudges and three sheen passes, then they stop. A permanent pulse on a
   donate button reads as pressure, and this page spends the rest of its copy
   telling people nothing is being taken from them. Finite keeps both true. */
.hero-support,.footer-support,.mhero__support{
  overflow:hidden;
  animation:tagSlap .55s cubic-bezier(.34,1.56,.64,1) .9s both,
            nudge 1.5s ease-in-out 2.3s 3 none}
/* Only the two in normal flow need a containing block for the sheen. The hero
   one is already absolutely positioned onto the artwork, and setting relative
   here knocked it out of place. */
.footer-support,.mhero__support{position:relative}
.footer-support{animation-delay:.2s, 1.6s}
.hero-support::after,.footer-support::after,.mhero__support::after{
  content:"";position:absolute;top:0;bottom:0;left:-45%;width:42%;pointer-events:none;
  background:linear-gradient(100deg,transparent 0%,rgba(255,255,255,.5) 50%,transparent 100%);
  transform:skewX(-18deg);
  animation:sheen 2.4s ease-in-out 1.5s 3 both}
.footer-support::after{animation-delay:.8s}

@keyframes tagSlap{
  0%  {opacity:0;transform:scale(.8) rotate(-5deg)}
  55% {opacity:1;transform:scale(1.07) rotate(1.6deg)}
  78% {transform:scale(.98) rotate(-.7deg)}
  100%{opacity:1;transform:none}
}
@keyframes nudge{
  0%,100%{transform:none}
  28%{transform:scale(1.055) rotate(-1.1deg)}
  58%{transform:scale(.995) rotate(.4deg)}
}
@keyframes sheen{
  0%       {left:-45%;opacity:0}
  10%      {opacity:1}
  48%,100% {left:132%;opacity:0}
}
.preset,.seg,.btn,.link,.footer-support{transition:background .16s ease,color .16s ease,
  filter .16s ease,transform .16s ease}
.preset:hover,.footer-support:hover{transform:translateY(-2px)}
.btn:hover:not(:disabled){transform:translateY(-2px) rotate(-.3deg)}

@media (min-width:700px) and (max-width:1100px){
  .mhero{padding:52px 32px 48px}
  .mhero > *{max-width:min(560px,62%)}
  .stage,.results,.site-footer{max-width:900px;margin-inline:auto}
  .layer{padding:34px 32px 38px}
  .results{padding:30px 32px 34px}
  .recent-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .presets{grid-template-columns:repeat(4,minmax(0,1fr))}
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *{transition:none!important;animation:none!important}
  .canvas,.brush,.hero-support,.footer-support,.mhero__support{opacity:1;transform:none}
  .hero-support::after,.footer-support::after,.mhero__support::after{display:none}
  .hero-fx,.mhero-fx{display:none}
}

/* ---------- Classes app.js emits that had no rule ---------- */
.batch__index{color:#8fdfe8;font-family:Consolas,ui-monospace,monospace;font-size:13px}
.flag--info{border-color:var(--teal)}
.link-button{border:0;background:transparent;padding:.25cqw 0;color:var(--teal-lift);
  text-transform:uppercase;font-size:.72cqw;cursor:pointer}
.link-button:hover{text-decoration:underline}
.link-button--danger{color:#f08a76}
.link-button:focus-visible{outline:3px solid var(--teal-lift);outline-offset:2px}
.saved-set__name{font-weight:600;color:#e6eae7;overflow-wrap:anywhere}
.saved-set__actions{display:flex;gap:.7cqw;flex-shrink:0}

@media (max-width:1100px){
  .link-button{font-size:13px;padding:5px 0;min-height:30px}
  .saved-set__name{font-size:14px}
  .saved-set__actions{gap:14px}
}
