:root{
  --ink:oklch(20.1% 0.027 305.2);
  --ink-2:oklch(39.5% 0.035 303.1);
  --ink-3:oklch(53% 0.03 302.2);
  --line:oklch(92.7% 0.017 308.3);
  --line-2:oklch(86.7% 0.034 304.5);
  --paper:oklch(96.8% 0.009 308.4);
  --card:oklch(100% 0 0);
  --field:oklch(98.7% 0.0041 301.4);
  --brand:oklch(55.5% 0.145 316.5);
  --brand-2:oklch(52.3% 0.219 272.3);
  --brand-3:oklch(55.9% 0.1074 78.3);
  --wash:oklch(95.6% 0.02 308.2);
  --good:oklch(51.5% 0.0946 161.9);   /* see the contrast note below */
  --good-w:oklch(95.8% 0.013 167.2);
  --r:16px;
  --r-sm:11px;
  /* Do not lighten --good. It is used at 12px weight 400, which is normal
     text, so it needs 4.5:1. At 51.5% it gives 4.77 on --good-w, 5.37 on
     --card and 4.89 on --paper. A lightness above about 52% fails one of
     them. */
  --shadow:0 1px 2px rgba(30,16,48,.04), 0 12px 32px -16px rgba(60,30,100,.16);
}
*{box-sizing:border-box}
html,body{margin:0}
body{
  background:
  linear-gradient(0deg, rgba(250, 248, 252, 0.97) 0%, rgba(255, 255, 255,0.97) 100%);
  background-attachment:fixed;
  color:var(--ink-3);
  font-family:Inter,system-ui,-apple-system,sans-serif;
  font-size:14px;line-height:1.55;
  -webkit-font-smoothing:antialiased;
}
button{font:inherit;color:inherit;cursor:pointer}
input,textarea{font:inherit;color:var(--ink);}
:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
/* Focus moves to the new step's heading on every step change, so the indicator
   has to show for programmatic focus too. :focus-visible does not fire for a
   scripted focus() on a heading, so the modality is tracked in script and
   .kb-focus stands in for it: set when the step was changed from the keyboard,
   cleared on the next pointerdown. That is what :focus-visible would do here if
   it fired.

   The ring itself is unchanged, 2px of --brand. A mouse user simply never sees
   it, which is the point: focus still moves for everybody. */
.step h1[tabindex="-1"].kb-focus:focus{outline:2px solid var(--brand);outline-offset:6px;border-radius:4px}

/* Available to a screen reader, absent from the page. Carries the step position
   into the heading's accessible name so one announcement says both which step
   this is and how many remain. */
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* ---------- chrome ---------- */
.topbar{display:flex;align-items:center;justify-content:space-between;padding:15px 45px}
.brandmark{display:flex;align-items:center;gap:9px;}
.brandmark img {width: 170px;}
.pill{font-size:13px;color:var(--ink-3);text-align:center;text-wrap-style:balance;background:rgba(255,255,255,.7);border:1px solid var(--line);padding:6px 13px;border-radius:20px}

.shell{max-width:780px;margin:0 auto;padding:10px 20px 40px}

/* ---------- progress ---------- */
/* margin 9/15 plus padding 5 is the same 14 top and 20 bottom the rail has
   always occupied. The five pixels are moved from margin into padding so the
   focus ring has somewhere to be drawn: overflow:hidden clips at the padding
   box, and with zero vertical padding a 2px ring offset by 2px was clipped
   entirely. The rail has no background and no border, so nothing about this is
   visible. Horizontal stays at 4px, where the ring lands flush with the clip
   edge rather than outside it. */
.rail{display:flex;gap:22px;margin:9px 0 15px;padding:5px 4px;overflow:hidden}
.rail div{flex:1;min-width:0}

/* Real buttons, so Enter and Space work natively and focus needs no help, and
   then every user-agent default that would change how they look is reset. They
   must be indistinguishable from the divs they replaced. flex and min-width are
   restored here because `.rail div` no longer reaches them. */
.rail>button{
  flex:1;min-width:0;display:block;
  appearance:none;-webkit-appearance:none;
  background:none;border:0;border-radius:0;box-shadow:none;
  margin:0;padding:0;
  font:inherit;letter-spacing:inherit;color:inherit;text-align:left;
  text-transform:none;cursor:default;
}
/* A disabled step must look exactly like an upcoming step does today, so the
   user agent's greying is refused outright. */
.rail>button:disabled{color:inherit;opacity:1;-webkit-text-fill-color:currentColor}
.rail .n{font-size:11px;font-weight:400;color:var(--ink-3);letter-spacing:.04em;font-variant-numeric:tabular-nums}
.rail .bar{height:2px;margin-top:7px;background:var(--line-2);border-radius:2px;overflow:hidden}
.rail .bar i{display:block;height:100%;width:0;background:var(--brand);border-radius:2px;transition:width .45s ease}
.rail .done .bar i,.rail .now .bar i{width:100%}
.rail .now .bar i{width:60%}
.rail .now .n,.rail .done .n{color:var(--brand-3)}
.rail .t{font-size:12px;color:var(--ink-3);margin-top:6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rail .now .t{color:var(--ink);font-weight:500}

/* Hover on completed steps only: never the current step, never one not yet
   reached, both of which are disabled. Colour only, because anything that
   changes a size would move the row. The transition is killed by the blanket
   rule at the foot of this file under reduced motion, which leaves an instant
   colour change rather than a frozen one. The focus ring is the global
   :focus-visible rule and is not restated here. */
.rail>button:not(:disabled){cursor:pointer}
.rail>button:not(:disabled) .n,
.rail>button:not(:disabled) .t{transition:color .15s ease}
.rail>button:not(:disabled):hover .n{color:var(--brand-2)}
.rail>button:not(:disabled):hover .t{color:var(--ink)}

/* ---------- panel ---------- */
.panel{background:var(--card);border:1px solid var(--line);border-radius:26px;box-shadow:var(--shadow);padding:45px}
.step{display:none}
.step.on{display:block;animation:in .3s ease both}
@keyframes in{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}

.kicker{font-size:13px;color:var(--brand-3) !important;font-weight:500;margin:0 0 12px}
/* Playfair Display's capitals overshoot the line box at 1.1, which clipped the
   tops of the letters. Not a split regression: this rule is unchanged from
   before the CSS was extracted. */
h1{font-family:'Playfair Display',Georgia,serif;font-weight:500;font-size:clamp(30px,4.6vw,36px);color:var(--ink);line-height:1.18;letter-spacing:-.012em;margin:0 0 12px;padding-top:2px}
.sub{color:var(--ink-2);margin:0 0 28px;max-width:52ch;font-size:16px}

/* ---------- tabs ---------- */
.tabs{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:18px}
/* min-height rather than more padding: the tabs sit on one row at desktop and
   wrap to three at 375, so growing the padding would push the wrap point and
   change the layout. min-height lifts the box to 44 and leaves the horizontal
   rhythm exactly where it was. 44 is 2.5.5 Target Size (Enhanced), AAA. Both
   already passed 2.5.8 at AA, which asks 24. */
.tab{display:inline-flex;align-items:center;gap:8px;background:var(--card);border:1px solid var(--line-2);border-radius:30px;padding:9px 17px;min-height:44px;font-size:14px;color:var(--ink-2);transition:.15s}
.tab:hover{border-color:var(--brand-3);color:var(--ink)}
.tab.on{background:var(--brand-3);border-color:var(--brand-3);color:#fff;font-weight:500}
.tab svg{flex:none}

/* ---------- import field ---------- */
.field{display:flex;align-items:center;gap:12px;background:var(--field);border:1px solid var(--line-2);border-radius:var(--r);padding:8px 8px 8px 18px;transition:.15s}
.field:focus-within{border-color:var(--brand);background:#fff;box-shadow:0 0 0 3px var(--wash)}
.field input{border:0;outline:0;background:none;width:100%;padding:12px 0;font-size:14px}
.field input::placeholder{color:var(--ink-3)}
.go{background:var(--brand);color:#fff;border:0;border-radius:11px;padding:12px 22px;font-weight:400;white-space:nowrap;transition:.15s}
.go:hover{background:var(--brand-2)}
.go[disabled]{background:var(--line-2);color:#fff;cursor:not-allowed}

.hint{margin-top:12px;font-size:14px;color:var(--ink-3)}
.hint button{background:none;border:0;color:var(--brand-2);font-weight:500;text-decoration:underline;text-underline-offset:3px;padding:0}

.results{margin-top:10px;border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.result{display:flex;gap:13px;align-items:center;width:100%;text-align:left;background:#fff;border:0;border-bottom:1px solid var(--line);padding:14px 17px;cursor:pointer;transition:background .12s}
.result:last-child{border-bottom:0}
/* Hover uses --brand-2, the same token .go and .btn already hover to. */
.result:hover{background:var(--field);}
.result:hover .mt,.result:hover .chev{color:inherit;opacity:1}
/* --ink is the darkest token, so the ring holds well past 3:1 on the white
   row and on the --brand-2 hover fill alike. */
.result:focus-visible{outline:3px solid var(--ink);outline-offset:-3px}
/* The chosen row is held briefly before the step advances. Dimming the rest
   makes the choice unmistakable even when the pointer is still on the row. */
.results.choosing .result{opacity:.45}
.results.choosing .result[aria-pressed="true"]{opacity:1;background:var(--brand-2);color:#fff}
.results.choosing .result[aria-pressed="true"] .mt,
.results.choosing .result[aria-pressed="true"] .chev{color:#fff;opacity:1}
@media(prefers-reduced-motion:reduce){.result,.results .result{transition:none}}
.result .nm{font-weight:400;font-size:15px}
.result .mt{font-size:12px;color:var(--ink-3);font-weight:400}
.result .rbody{min-width:0;flex:1}
.result .rbody .nm,.result .rbody .mt{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* metadata that carries signal earns a badge; the category does not. Keep
   this scoped to .result: an unscoped .pill selector collides with the topbar
   pill and silently restyles it. The badge deliberately shares .ok's values
   further down, so the two affirmative marks read as one thing. */
.chev{flex:none;color:var(--ink-3);opacity:.5;transition:.15s}
.result:hover .chev,.result:focus-visible .chev{opacity:1;transform:translateX(2px)}
.avatar{width:36px;height:36px;border-radius:10px;flex:none;background:var(--wash);color:var(--brand-2);display:grid;place-items:center;font-weight:400;font-size:14px;overflow:hidden}
.avatar img{width:100%;height:100%;object-fit:cover;display:block}
.avatar .glyph{width:58%;height:58%;background:currentColor;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-size:contain;mask-size:contain}

textarea{width:100%;min-height:200px;resize:vertical;line-height:1.8;padding:15px;border:1px solid var(--line-2);border-radius:var(--r);background:var(--field);outline:0}
textarea:focus{border-color:var(--brand);background:#fff;box-shadow:0 0 0 3px var(--wash)}

.trades{margin-top:20px;border-top:1px solid var(--line);padding-top:18px}
.trades-top{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:13px}
.trades-top .lead{font-size:14px;font-weight:500}
.tsearch{display:flex;align-items:center;gap:8px;background:var(--field);border:1px solid var(--line-2);border-radius:22px;padding:7px 14px;min-width:210px;flex:1;max-width:290px}
.tsearch:focus-within{border-color:var(--brand);background:#fff}
.tsearch input{border:0;outline:0;background:none;width:100%;font-size:14px}
.tsearch .clr{background:none;border:0;color:var(--ink-3);padding:0;font-size:16px;line-height:1;display:none}
.tsearch.has .clr{display:block}
.shuffle{width:34px;height:34px;flex:none;border-radius:50%;background:#fff;border:1px solid var(--line-2);display:grid;place-items:center;color:var(--ink-3);transition:.2s}
.shuffle:hover{border-color:var(--brand);color:var(--brand-2)}
.shuffle.spin svg{animation:sp .5s ease}
@keyframes sp{to{transform:rotate(360deg)}}
.idea-row{display:flex;flex-wrap:wrap;gap:8px;align-items:center;min-height:34px}
.idea{background:#fff;border:1px solid var(--line-2);border-radius:20px;padding:7px 15px;font-size:13px;color:var(--ink-2);transition:.15s}
.idea:hover{border-color:var(--brand-3);color:var(--brand-3)}
.idea.on{background:var(--brand-3);border-color:var(--brand-3);color:#fff;font-weight:500}

/* Chip loader. The spinner is absolutely positioned and the label is made
   transparent rather than removed, so the chip keeps its width: a chip that
   grew on click could bump to the next line in this wrapping row. The
   @keyframes sp above is shared with .shuffle.spin, no new animation.
   .sp carries its own colour because .idea.loading{color:transparent} is what
   currentColor would otherwise inherit, which would hide the spinner too. */
.idea{position:relative}
.idea .sp{position:absolute;top:50%;left:50%;width:13px;height:13px;margin:-6.5px 0 0 -6.5px;display:none}
.idea.loading{color:transparent}
.idea.loading .sp{display:block;color:#fff;animation:sp .7s linear infinite}
.idea-row.busy .idea:not(.loading){opacity:.45;pointer-events:none}

/* The blanket rule at the foot of this file kills every animation, so a
   rotating spinner would sit frozen and read as broken. Dim the chip and keep
   its label instead. */
@media (prefers-reduced-motion:reduce){
  .idea.loading{color:#fff;opacity:.6}
  .idea.loading .sp{display:none}
}
.none{font-size:13px;color:var(--ink-3)}

/* ---------- their own photos ---------- */
.shots{display:flex;gap:7px;padding:0 18px 16px;overflow-x:auto;scrollbar-width:thin}
.shots img{width:104px;height:78px;flex:none;border-radius:9px;object-fit:cover;background:var(--wash)}
.shots:empty{display:none}

/* ---------- connect (facebook / instagram) ---------- */
.connect{border:1px solid var(--line-2);border-radius:var(--r);background:var(--field);padding:22px}
.connect .ct{font-weight:500;font-size:15px;margin-bottom:4px}
.connect .cs{font-size:14px;color:var(--ink-3);margin-bottom:16px;max-width:46ch}
.connect .go{width:auto}
.connect .why{margin-top:14px;font-size:12px;color:var(--brand-3);display:flex;gap:9px;align-items:flex-start;line-height:1.4}
.connect .why svg{flex:none;margin-top:2px;color:var(--brand-3)}
/* .connect .why sets display:flex, which beats the user agent rule for
   [hidden], so hiding it from script needs this. Same trap as .chip below. */
.connect .why[hidden]{display:none}

/* Meta pending state. The transition is killed by the blanket reduced-motion
   rule at the foot of this file, which leaves an instant change of background
   rather than a frozen one. */
.connect.meta-pending{
  background:#faf9f7;
  border-left:3px solid #e8a020;
  transition:background .2s, border-left-color .2s;
}

/* Both Meta tabs read as pending whether or not they are selected, because
   the path is pending either way.

   Muted by tinting the fill and DARKENING the label, not by lightening the
   fill under white text. --card is oklch(100% 0 0), so every mix toward it
   lightens: white on a 65% mix is 2.59:1 and on a 50% mix is 2.04:1, both far
   under the 4.5:1 that 14px text needs. Dark text on a 35% mix is 5.86:1,
   which leaves real margin rather than the thin one that put --good in this
   file's history. */
.tab[data-src="facebook"],
.tab[data-src="instagram"],
.tab[data-src="facebook"].on,
.tab[data-src="instagram"].on{
 opacity: .7;
}
/* Selection still has to be legible, so it moves to the border and the weight
   rather than to the fill. */
.tab[data-src="facebook"].on,
.tab[data-src="instagram"].on{border-color:var(--brand-3);font-weight:500}

/* ---------- found ---------- */
.found{border:1px solid var(--line);color:var(--ink);border-radius:var(--r);overflow:hidden}
.found-head{display:flex;gap:14px;align-items:center;padding:18px 20px;background:linear-gradient(180deg,var(--wash),#fff)}
.found-head .nm{font-weight:400;font-size:16px}
.found-head .mt{font-size:13px;color:var(--ink-3)}
.rows{margin:0;padding:4px 20px 12px;list-style:none}
.rows li{display:flex;gap:12px;align-items:center;padding:11px 0;border-bottom:1px solid var(--line);font-size:15px}
.rows li:last-child{border-bottom:0}
.rows .k{color:var(--ink-3);width:130px;flex:none;font-size:14px}
.rows .v{font-weight:450}
.result .badge,
.ok{margin-left:auto;color:var(--good);background:var(--good-w);font-size:12px;font-weight:400;padding:3px 10px;border-radius:20px;white-space:nowrap}

.note{margin-top:18px;background:var(--wash);border-radius:var(--r);padding:16px 19px;font-size:14px;color:var(--brand-2)}
.note b{font-weight:400}

label.lbl{display:block;color:var(--ink);font-weight:500;font-size:14px;margin:28px 0 4px}
.lbl-h{font-size:13px;color:var(--ink-3);margin:0 0 10px}

/* ---------- dropzone ---------- */
.drop{border:1px dashed var(--line-2);border-radius:var(--r);background:var(--field);padding:24px;text-align:center;transition:.15s;cursor:pointer}
.drop:hover,.drop.over{border-color:var(--brand);background:var(--wash)}
.drop .di{width:40px;height:40px;border-radius:11px;background:var(--wash);color:var(--brand-2);display:grid;place-items:center;margin:0 auto 11px}
.drop .dt{font-weight:500;font-size:14px}
.drop .ds{font-size:13px;color:var(--ink-3);margin-top:3px}
.files{display:flex;flex-wrap:wrap;gap:9px;margin-top:13px}
.file{display:inline-flex;align-items:center;gap:9px;background:#fff;border:1px solid var(--line-2);border-radius:11px;padding:4px 6px 4px 11px;font-size:13px;max-width:100%}
.file .th{width:26px;height:26px;border-radius:6px;object-fit:cover;flex:none;background:var(--wash)}
.file .fn{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:150px}
.file .rm{background:none;border:0;color:var(--ink-3);font-size:17px;line-height:1;
  min-width:44px;min-height:44px;display:grid;place-items:center;border-radius:9px;flex:none}
.file .rm:hover{color:var(--ink);background:var(--wash)}

/* Upload state. Three states, told apart by wording and weight rather than by
   colour alone, so it reads the same to anyone who cannot separate the hues.
   Every value here is an existing token.

   The chip is two rows: the file on top, what happened to it underneath. That
   keeps a long message and a long filename both readable at 375px, where
   putting them on one line squeezed the name down to an ellipsis. */
.file{flex-wrap:wrap}
.file .th{order:1}
.file .fn{order:2;flex:1 1 auto}
.file .rm{order:3}
.file .fs{order:4;flex-basis:100%;font-size:12.5px;color:var(--ink-3);padding:0 2px 2px 35px}
.file .rt{order:5}
.file[data-state="ok"] .fs{color:var(--good)}
.file[data-state="err"]{border-color:var(--ink-3);background:var(--paper)}
.file[data-state="err"] .fs{color:var(--ink);font-weight:500}
.file[data-state="err"] .fn{text-decoration:line-through;color:var(--ink-3)}
.file[data-state="up"] .th{opacity:.55}
.file .rt{background:none;border:1px solid var(--line-2);border-radius:9px;color:var(--ink);
  font-size:12.5px;padding:0 12px;min-height:44px;min-width:44px;white-space:nowrap;flex:none;
  margin:0 0 4px 35px}
.file .rt:hover{border-color:var(--brand);color:var(--brand)}

/* A quiet pulse while a file is in the air, and none at all for anyone who has
   asked for less movement. */
@keyframes upPulse{50%{opacity:.45}}
.file[data-state="up"] .fs{animation:upPulse 1.1s ease-in-out infinite}
@media (prefers-reduced-motion:reduce){ .file[data-state="up"] .fs{animation:none} }

.logo-zone{display:flex;gap:16px;align-items:center;border:1px dashed var(--line-2);border-radius:var(--r);background:var(--field);padding:18px 20px;cursor:pointer}
.logo-zone:hover,.logo-zone.over{border-color:var(--brand);background:var(--wash)}
.logo-prev{width:56px;height:56px;border-radius:12px;background:#fff;border:1px solid var(--line);display:grid;place-items:center;flex:none;overflow:hidden}
.logo-prev img{width:100%;height:100%;object-fit:contain}
.switch{display:flex;align-items:center;gap:12px;margin-top:14px;padding:14px 17px;border:1px solid var(--line);border-radius:var(--r);font-size:14px}
.switch .tgl{width:42px;height:24px;border-radius:20px;background:var(--line-2);position:relative;flex:none;transition:.18s;border:0;padding:0}
.switch .tgl::after{content:"";position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;background:#fff;transition:.18s}
.switch .tgl.on{background:var(--brand)}
.switch .tgl.on::after{left:21px}
.switch.off{opacity:.5}
.switch.off .tgl{cursor:not-allowed}

/* ---------- chips ---------- */
.chips{display:flex;flex-wrap:wrap;gap:9px}
.chip{background:#fff;border:1px solid var(--line-2);border-radius:24px;padding:10px 17px 10px 13px;font-size:14px;display:inline-flex;align-items:center;gap:8px;transition:.15s}
.chip .ico{width:17px;height:17px;flex:none;display:grid;place-items:center;border-radius:50%;color:var(--ink-3);transition:.15s}
.chip.on .ico{background:rgba(255,255,255,.22);color:#fff}
.chip:hover .ico{color:var(--brand)}
.chip.on:hover .ico{color:#fff}
.chip.fixed .ico{color:var(--brand-2)}
.chip:hover{border-color:var(--brand-2)}
.chip.on{background:var(--brand-2);border-color:var(--brand-2);color:#fff;font-weight:500}
.chip.fixed{background:var(--wash);border-color:transparent;color:var(--brand-2);font-weight:500;cursor:default}
/* .chip sets display:inline-flex, which beats the user agent rule for [hidden],
   so the attribute needs saying again here or a hidden chip still shows. */
.chip[hidden]{display:none}
/* Show more sits with the chips but is not one of them: no tick, no fill, and
   it never carries a page name. */
.chip.more{border-style:dashed;color:var(--ink-3);font-weight:400}
.chip.more:hover{border-color:var(--brand);color:var(--brand)}

/* ---------- picks ---------- */
.picks{display:grid;grid-template-columns:repeat(auto-fill,minmax(152px,1fr));gap:11px;align-items:stretch}
.pick{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:13px;text-align:center;transition:.15s}
.pick:hover{border-color:var(--line-2)}
.pick.on{border-color:var(--brand);box-shadow:0 0 0 2px var(--wash); color:var(--ink);}
.swatches{display:flex;height:36px;border-radius:9px;overflow:hidden;margin-bottom:10px}
.swatches span{flex:1}
.pick .nm{font-size:13px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pick .auto{height:36px;display:flex;align-items:center;gap:7px;color:var(--brand-2);font-weight:400;font-size:14px;margin-bottom:10px}
/* Each family name is set in its own face, heading above body. Do not declare
   font-family here: it is written per element from FONTS, which is what stops
   this file disagreeing with what is sent. */
.ft-h{display:block;font-size:21px;line-height:1.25;font-weight:600;color:var(--ink)}
.ft-b{display:block;font-size:13.5px;line-height:1.4;font-weight:400;color:var(--ink-3);margin-top:3px}

/* ---------- actions ---------- */
.actions{display:flex;flex-wrap:wrap;align-items:center;gap:12px 8px;margin-top:34px;padding-top:24px;border-top:1px solid var(--line)}
/* Do not add `#s1 .actions .btn{margin-left:0}` here. Continue sits at the
   right on every step, and moving it on this one alone is the inconsistency,
   not the fix. */
@media(max-width:560px){#s1 .actions .btn{width:100%}}
.btn{background:var(--brand);color:#fff;border:0;border-radius:8px;padding:15px 28px;text-transform: uppercase;font-weight:600;letter-spacing:0.03rem;margin-left:auto;transition:.15s}
.btn:hover{background:var(--brand-2)}
.btn[disabled]{background:var(--line-2);cursor:not-allowed}
.back{background:none;border:0;color:var(--ink-3);padding:15px 6px}
.back:hover{color:var(--ink)}
.skip{background:none;border:0;color:var(--ink-3);text-decoration:underline;text-underline-offset:3px;padding:15px 10px}
.skip:hover{color:var(--brand-2)}

/* ---------- website language ---------- */
/* A native select on purpose: twenty six options, and keyboard handling and
   the phone picker for free. Keep the label visible and bound with for, never
   a placeholder: this control decides what language the finished website is
   written in, and that is not recoverable by guessing. */
.langpick{display:flex;flex-direction:column;gap:3px;min-width:0}
.lang-lbl{font-size:12px;color:var(--ink-3);line-height:1.2}
#lang{
  font:inherit;font-size:13.5px;color:var(--ink);
  background:var(--field);border:1px solid var(--line-2);border-radius:var(--r-sm);
  padding:0 30px 0 12px;min-height:44px;max-width:230px;
  appearance:none;
  /* The chevron is drawn from --ink-3 rather than added as a colour literal. */
  background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),
                   linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-size:5px 5px,5px 5px;
  background-position:calc(100% - 15px) calc(50% + 1px),calc(100% - 10px) calc(50% + 1px);
  background-repeat:no-repeat;
  transition:.15s;
}
#lang:hover{border-color:var(--brand-3)}
#lang:focus{border-color:var(--brand)}

/* ---------- questions people ask ---------- */
/* Outside the form and outside .shell, so no step rule can reach it. Every
   value is an existing token. */
.faq{max-width:780px;margin:0 auto;padding:0px 20px 30px}
.faq h2{font-family:'Playfair Display',Georgia,serif;font-weight:500;
  font-size:26px;color:var(--ink);margin:0 0 14px}
.faq-list{border-top:1px solid var(--line)}
.faq-item{border-bottom:1px solid var(--line)}
/* The heading carries no visual weight of its own: it exists so the questions
   are a real heading level for anyone navigating by headings. */
.faq-h{margin:0;font-size:inherit;font-weight:inherit}
.faq-q{
  display:flex;align-items:center;gap:15px;width:100%;
  background:none;border:0;text-align:left;
  min-height:60px;padding:15px 5px;
  font-size:15px;font-weight:500;color:var(--ink);
}
.faq-q:hover{color:var(--brand)}
.faq-t{flex:1 1 auto}
/* A plus that becomes a minus, drawn from currentColor so it needs no token
   and no image. aria-hidden, because aria-expanded already says the state. */
.faq-i{flex:none;position:relative;width:13px;height:13px;color:var(--ink-3)}
.faq-i::before,.faq-i::after{content:'';position:absolute;background:currentColor;
  border-radius:1px;transition:transform .18s ease,opacity .18s ease}
.faq-i::before{left:0;top:6px;width:13px;height:1.5px}
.faq-i::after{left:5.75px;top:0;width:1.5px;height:13px}
.faq-q[aria-expanded="true"] .faq-i::after{transform:scaleY(0);opacity:0}
.faq-q[aria-expanded="true"] .faq-i{color:var(--brand)}
.faq-a{padding:0 2px 18px;max-width:64ch}
.faq-a p{margin:0;font-size:14.5px;line-height:1.65;color:var(--ink-2)}
@media (prefers-reduced-motion:reduce){
  .faq-i::before,.faq-i::after{transition:none}
}

/* =========================================
   AI Website Builder information
   ========================================= */

   .builder-info {
    width: min(100% - 40px, 760px);
    margin: 45px auto 45px;
    color: #272330;
  }
  
  .builder-info-intro {
    max-width: 640px;
  }
  
  .builder-info h2 {
    margin: 0 0 16px;
    font-family: "Playfair Display", Georgia, serif;
    font-size: clamp(25px, 3vw, 32px);
    line-height: 1.2;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: #211c29;
  }
  
  .builder-info-lead {
    font-size: 17px;
    line-height: 1.65;
    color: #3f3949;
  }
  
  .builder-info p {
    line-height: 1.7;
    color:var(--ink-2);
  }
  
  .builder-how {
    margin-top: 60px;
    padding-bottom:45px;
    border-bottom:1px solid #e7e0ed;
  }
  
  .builder-how > h2 {
    margin-bottom: 24px;
  }
  
  .builder-steps {
    display: flex;
    flex-direction:row;
    gap: 15px;
    list-style: none;
    margin: 0;
    padding: 0;
  }
  
  .builder-step {
    padding: 15px 15px 15px 0;
    border-right: 1px solid #e7e0ed;
  }
  .builder-step:last-child{
    padding: 15px 0;
    border-right:none;
  }
  .builder-step div {
    margin-top: 5px;
  }
  .builder-step-number {
    /* No width, height or flex here on purpose. They were declared and were
       inert: this span is display:inline, which ignores width and height, and
       flex applies only to a flex item, which it is not because the parent li
       is display:list-item. The marker measured 25x16 while the rules said 44.

       They are deleted rather than made real. The marker is decorative in a
       non-interactive list, so target size does not apply, and a genuine 44px
       box would move the spacing for nothing. Dead CSS that reads as an
       accessibility measure is worse than none: the next person auditing
       target sizes would see 44px and assume it was handled. */
    letter-spacing: 0.06em;
  }
  .builder-step-number img {
    /* The icons all carry a square 24x24 viewBox. A fixed 25 by 30 box stretched
       them 25% vertically. height:auto lets each one keep its own ratio, so an
       icon of a different shape added later is not distorted either. */
    width: 25px;
    height: auto;
  }
  .builder-step h3 {
    margin: 0 0 10px;
    font-size: 15px;
    line-height: 1.4;
    font-weight: 600;
    color: #272330;
  }
  
  .builder-step p {
    margin: 0;
    max-width: 590px;
  }
  
  .builder-info .builder-info-note {
    margin: 22px 0 0;
    padding-left: 15px;
    border-left: 2px solid var(--brand-3);
    font-style: italic;
    font-weight:500;
  }
  
  @media (max-width: 640px) {
    .builder-info {
      width: min(100% - 32px, 760px);
      margin-top: 40px;
      margin-bottom: 48px;
    }
  
    .builder-info h2 {
      font-size: 26px;
    }
  
    .builder-info-lead {
      font-size: 16px;
    }
  
    .builder-step {
      border-right: none;
      border-bottom:1px solid #e7e0ed;
    }
    .builder-steps {
      display:flex;
      flex-direction:column;
    }
  }

/* ---------- site footer ---------- */
/* Quiet by design. It must be findable, and it must not compete with the form. */
.site-foot{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:0 18px;
  padding:0 20px 34px;
  font-size:12.5px;color:var(--ink-3);
}
.site-foot a{
  color:var(--ink-3);text-decoration:underline;text-underline-offset:2px;
  display:inline-flex;align-items:center;min-height:44px;padding:0 6px;border-radius:6px;
}
.site-foot a:hover{color:var(--brand)}
.site-foot .foot-c{white-space:nowrap;padding:11px 0}
/* Subordinate to the form on purpose: same size and colour as the rest of the
   footer, with only the link itself underlined. It sits inside a sentence, so
   it cannot be the 44px flex box the other footer links are. The vertical
   padding is cancelled by an equal negative margin: the hit area reaches 44px
   without the line box growing, so the sentence still reads as one line. */
.site-foot .foot-signin{white-space:normal}
.site-foot .foot-signin a{
  color:var(--brand);
  display:inline;min-height:0;
  padding:14px 3px;margin:-14px 0;
}
@media(max-width:560px){ .site-foot{padding-bottom:26px} }

/* ---------- building ---------- */
.building{text-align:center;padding:26px 0 10px}
.ring{width:72px;height:72px;margin:0 auto 24px}
.ring circle{fill:none;stroke-width:5}
.ring .t{stroke:var(--line-2)}
.ring .p{stroke:var(--brand);stroke-linecap:round;transform-origin:50% 50%;transition:stroke-dashoffset .5s ease}

/* Working: the arc is a fixed three-quarter gap that spins, so motion is
   continuous for the whole wait and reads as activity rather than as an amount
   done. The arc only closes when the job actually reports done. */
.ring .p{transform:rotate(-90deg);animation:ring-spin 1.15s linear infinite}
.building[data-state="done"] .ring .p,
.building[data-state="failed"] .ring .p{animation:none;transform:rotate(-90deg)}
.building[data-state="failed"] .ring .p{stroke:#8A2B2B}
@keyframes ring-spin{to{transform:rotate(270deg)}}

/* The active stage pulses. Nothing else on the row moves, so the eye lands on
   the one thing that is genuinely happening. */
.task.on .dot{animation:dot-pulse 1.5s ease-in-out infinite}
@keyframes dot-pulse{0%,100%{box-shadow:0 0 0 0 rgba(148,84,171,.42)}55%{box-shadow:0 0 0 6px rgba(148,84,171,0)}}


/* The tick lands instantly at the end. With the usual 0.2s colour transition a
   frame existed in which the heading already said ready while the last stage
   was still mid-fade, which is exactly the thing this screen must never do. */
.building[data-state="done"] .dot{transition:none}
/* Same type size as the rest of this screen, not small print. The breathing
   room above is what separates it from the stage list: it is context, not a
   fourth stage. No animation or transition, so it reads identically on the
   prefers-reduced-motion path, where the blanket rule suppresses both. */
.first-draft{margin:40px auto 0;max-width:46ch;font-size:15px;line-height:1.6;color:var(--ink-3)}
.first-draft p{margin:0}
.first-draft .fd-lead{color:var(--ink-2);font-weight:500;margin-bottom:6px}
/* Untrue if the generation did not finish. */
.building[data-state="failed"] .first-draft{display:none}

.build-out{margin:22px auto 0;max-width:340px}
.build-out .go{display:inline-block;text-decoration:none;text-align:center}
.build-note{margin:14px auto 0;font-size:13.5px;color:var(--ink-3);line-height:1.55}
.build-note a{color:var(--brand)}
.tasks{width:100%;margin:0 auto;text-align:center}
.task{display:flex;gap:12px;align-items:center;justify-content:center;padding:10px 0;color:var(--ink-3);font-size:15px;transition:.2s}
.task.on,.task.done{color:var(--ink)}
.task.on{font-weight:500}
.dot{width:19px;height:19px;border-radius:50%;border:2px solid var(--line-2);flex:none;display:grid;place-items:center;transition:.2s}
.task.done .dot{background:var(--good);border-color:var(--good)}
.task.on .dot{border-color:var(--brand)}
.dot svg{display:none}
.task.done .dot svg{display:block}

@media (max-width:640px){
  .topbar{padding:15px;display:grid;grid-template-columns:0.85fr 1fr;}
  .brandmark img {width:150px}
  .panel{padding:30px 22px 26px;border-radius:20px}
  .rail{gap:10px}
  .rail .t{display:none}
  .shell{padding:0 15px 60px}
  .field{flex-wrap:wrap;padding:14px}
  #s3 .field{flex-wrap:nowrap}
  .field input{width:90%}
  .go{width:100%}
  #addpage.go {width:auto;}
  .rows .k{width:104px}
  .rows li{flex-wrap:wrap}
}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
