:root {
  color-scheme: light;   /* native scrollbars, inputs and pickers follow the theme we chose, not the OS */
  --bg: #f6f6f4;
  --surface: #ffffff;
  --surface-2: #f0efec;
  --ink: #16150f;
  --ink-2: #56534a;
  --ink-3: #86827a;
  --line: #e0ded7;
  --accent: #FAD000;   /* Vessel Yellow: fills, borders, outlines */
  --accent-ink: #16150f;
  --accent-text: #be9800;   /* the yellow as text */
  --available: #0f7a3d;
  --available-bg: #e6f4ea;
  --premium: #a15c00;
  --premium-bg: #fbf0dc;
  --premium-fill: #e6d78e;   /* premium buttons and ending chips, in both themes: darker than --premium-bg, so text on it is --premium-strong or --accent-ink */
  --premium-strong: #5c4400;   /* text and borders on --premium-fill, 5.2:1 */
  --taken: #b0243a;
  --taken-bg: #fbe8ea;
  --forsale: #6b3fb5;
  --forsale-bg: #f0eafc;
  --unknown: #6b6862;
  --unknown-bg: #eceae5;
  --radius: 10px;
  --card-pad: 60px;   /* the stuck toolbar lines its contents up with this, so it lives here */
  --bar: 68px;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

/* Light is the theme. Dark is a class on the root, put there on the way up by a line in the page
   head that asks the OS once — so switching themes while working is one class in the inspector
   rather than an OS setting, and nothing here has to be written twice. */
:root.dark {
  color-scheme: dark;
  --bg: #14140f;
  --surface: #242420;
  --surface-2: #2b2b24;
  --ink: #f2f0e9;
  --ink-2: #b6b2a8;
  --ink-3: #8a867d;
  --line: #33322c;
  --accent: #FAD000;
  --accent-ink: #16150f;
  --accent-text: #FAD000;
  --available: #6ddc9b;
  --available-bg: #16301f;
  --premium: #ecb45c;
  --premium-bg: #33260f;
  --taken: #f0899a;
  --taken-bg: #35171d;
  --forsale: #c4a6f5;
  --forsale-bg: #241a38;
  --unknown: #9c988f;
  --unknown-bg: #26251f;
}

* { box-sizing: border-box; }

/* The browser hides [hidden] by setting display:none, which any rule of our own that sets a
   display wins against — so a flex row stayed on screen however often the script hid it. This
   is the one place that is worth an !important: a class has to be able to lay an element out
   without quietly taking away the ability to hide it. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 15px/1.55 "Outfit", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.topbar { display:flex; align-items:center; justify-content:space-between; gap:16px; padding:14px 20px; border-bottom:1px solid var(--line); background:var(--surface); }
/* Its own layer, so its menus open over the page below, which may set up stacking layers of its own; under the drawer's backdrop (29). */
.topbar { position:relative; z-index:25; }
.topbar-right { display:flex; align-items:center; gap:10px; min-width:0; }

.topbar-right .icon { padding:6px 9px; }
/* On a phone the drawer's button sits in front of the name, which keeps to the left beside it. */
.topbar .brand { margin-right:auto; }

/* THE PROJECTS SIDEBAR */
/* Down the left, the way a chat app keeps its conversations. The page moves over to make room by
   --side, which is the one thing anything else needs to know about it: the footer, the toast and
   the toolbar that spreads the width of the window all read it. Open unless it was folded. */
:root { --side: 0px; }
@media (min-width: 561px) {
  body { --side: 264px; padding-left: var(--side); transition: padding-left .18s ease; }
  body.side-rail { --side: 56px; }
  /* Folded to a rail: the menu button and the new-project button, and nothing that needs a name. */
  body.side-rail .side-title, body.side-rail .side-list, body.side-rail .side-empty, body.side-rail .side-group, body.side-rail .side-new span { display:none; }
  body.side-rail .side-new { justify-content:center; margin-inline:8px; padding-inline:0; }
  /* The guest block on the rail: its icons, centred, and the login button without its words or its card. */
  body.side-rail .side-link span, body.side-rail .side-join-text, body.side-rail .side-join-btn span { display:none; }
  body.side-rail .side-link { justify-content:center; padding-inline:0; }
  body.side-rail .side-join { padding:0; background:none; box-shadow:none; }
  body.side-rail .side-join-btn { padding-inline:0; }
}
.sidebar { position:fixed; top:0; bottom:0; left:0; z-index:15; display:flex; flex-direction:column; width:var(--side); overflow:hidden; background:var(--surface-2); border-right:1px solid var(--line); transition:width .18s ease; }
.side-head { display:flex; align-items:center; gap:8px; padding:12px 10px 8px; }
.side-toggle { flex:none; }
.side-title { font-size:12px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--ink-3); white-space:nowrap; }
.side-list { flex:0 1 auto; min-height:0; overflow-y:auto; margin:0; padding:0 8px; list-style:none; }   /* as tall as its projects, then it scrolls, so New project follows the last of them */
.side-item { display:flex; align-items:center; gap:2px; border-radius:8px; }
.side-item:hover { background:var(--surface); }
/* The one open, marked the way a selected row is in the list: a stripe of the accent down its edge. */
.side-item.current { background:var(--surface); box-shadow:inset 3px 0 0 var(--accent); }
.side-name { flex:1; min-width:0; padding:15px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--ink); font-size:13.5px; text-decoration:none; }
.side-item.current .side-name { font-weight:600; }
.side-act { flex:none; display:inline-flex; align-items:center; justify-content:center; width:28px; height:28px; padding:0; border:0; border-radius:6px; background:none; color:var(--ink-3); cursor:pointer; }
.side-act:hover { background:var(--surface-2); color:var(--ink); }
.side-act.bin:hover { color:var(--taken); }
/* On the row under the pointer only, as the idea rows' buttons are; a phone never hides them. */
@media (hover: hover) {
  .side-act { opacity:0; }
  .side-item:hover .side-act, .side-item:focus-within .side-act { opacity:1; }
}
.side-rename { flex:1; min-width:0; margin:3px 4px; padding:5px 8px; border:1px solid var(--accent); border-radius:6px; background:var(--bg); color:var(--ink); font:inherit; font-size:13.5px; }
.side-rename:focus { outline:none; }
.side-empty { margin:4px 18px; }
/* Others' projects, folded under their own heading; appears with the first one shared with you. */
.side-group { flex:0 1 auto; min-height:0; overflow-y:auto; margin-top:6px; }
	.side-group > summary { display:flex; align-items:center; gap:6px; padding:10px 18px 6px; cursor:pointer; list-style:none; }
	.side-group > summary::-webkit-details-marker { display:none; }
	.side-group > summary::after { content:""; width:6px; height:6px; margin-top:-3px; border:solid currentColor; border-width:0 1.5px 1.5px 0; transform:rotate(45deg); transition:transform .15s ease; }   /* chevron: down when open */
	.side-group:not([open]) > summary::after { margin-top:0; transform:rotate(-45deg); }
	.side-group .side-list { overflow:visible; }
.side-new { display:flex; align-items:center; gap:8px; margin:8px; padding:9px 12px; border:1px dashed var(--line); border-radius:8px; background:none; color:var(--accent-text); font:inherit; font-size:13.5px; font-weight:600; cursor:pointer; white-space:nowrap; }
.side-new:hover { border-color:var(--accent); background:var(--surface); }
/* On a phone the sidebar is a drawer, shut until asked for, with its own button in the header —
   scoped to the header, since button.icon's display would otherwise put it on a wide screen too. */
.topbar .side-open, .pool-bar .side-open { display:none; }
.side-backdrop { position:fixed; inset:0; z-index:29; background:rgb(0 0 0 / 0.38); }
/* GUEST BLOCK: AT THE FOOT OF THE MENU, ONLY WHILE LOGGED OUT */
.side-guest { display:flex; flex-direction:column; gap:10px; margin-top:auto; padding:8px; }
body:not(.signed-out) .side-guest { display:none; }
.side-links { display:flex; flex-direction:column; gap:2px; }
.side-link { display:flex; align-items:center; gap:10px; padding:8px 12px; border-radius:8px; color:var(--ink-2); font-size:13.5px; text-decoration:none; white-space:nowrap; }
	.side-link:hover { background:var(--surface); color:var(--ink); }
	.side-link svg { flex:none; color:var(--ink-3); }
.side-join { padding:14px; border-radius:var(--radius); background:var(--surface); box-shadow:inset 0 0 0 1px var(--line); }
.side-join-text { margin:0 0 12px; font-size:12.5px; line-height:1.45; color:var(--ink-3); }
	.side-join-text b { display:block; margin-bottom:2px; font-size:13.5px; color:var(--ink); }
.sidebar .side-join-btn { display:flex; align-items:center; justify-content:center; gap:8px; width:100%; padding:10px 14px; font-size:13px; font-weight:600; text-transform:none; white-space:nowrap; }   /* beats button.primary's wide pill, which squeezed the icon out */
	.side-join-btn svg { flex:none; }
@media (max-width: 560px) {
  .topbar .side-open { display:inline-flex; }
  .pool-bar.stuck .side-open { display:inline-flex; flex:none; }   /* only once the header holding the first one has scrolled away */
  .sidebar { width:min(86vw, 300px); z-index:30; transform:translateX(-100%); transition:transform .22s cubic-bezier(.2,.7,.3,1); }
  body.side-drawer .sidebar { transform:none; box-shadow:10px 0 34px rgb(0 0 0 / 0.26); }
}
.history { position:relative; }
.history > button { display:flex; align-items:center; gap:6px; max-width:180px; padding:6px 12px; font-size:13px; }
.history .chev { flex:none; font-size:10px; opacity:0.6; }
.menu { position:absolute; right:0; top:calc(100% + 6px); z-index:30; min-width:260px; max-width:min(88vw, 360px); max-height:min(60vh, 420px); overflow-y:auto; padding:6px; border:1px solid var(--ink-3); border-radius:10px; background:var(--surface); box-shadow:0 18px 44px rgb(0 0 0 / 0.30), 0 2px 6px rgb(0 0 0 / 0.16); }
.menu-sep { height:1px; margin:6px 4px; background:var(--line); }
.menu-item { display:flex; align-items:baseline; justify-content:space-between; gap:12px; width:100%; text-align:left; padding:8px 10px; border:0; border-radius:7px; background:none; color:inherit; font:inherit; font-size:13px; }
.menu-item:hover { background:var(--surface-2); }
.menu-balance { display:inline-flex; align-items:center; gap:5px; align-self:center; font-weight:700; font-variant-numeric:tabular-nums; }
.menu-item:has(.menu-icon) { justify-content:flex-start; align-items:center; }
.menu-icon { flex:none; color:var(--ink-2); }
.menu-label { flex:1; }
.menu-item.new { font-weight:600; color:var(--accent-text); }
.menu-item.current { background:var(--surface-2); font-weight:600; }
.menu-label { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.menu-date { flex:none; color:var(--ink-3); font-size:11px; font-variant-numeric:tabular-nums; }

.brand { display:inline-flex; align-items:center; color:var(--ink); text-decoration:none; }
.brand .logo { display:block; height:24px; width:auto; fill:currentColor; }
.brand .logo .dot { fill:var(--accent); }

.badge {
  padding: 3px 9px;
  border-radius: 99px;
  background: var(--surface-2);
  color: var(--ink-2);
  border: 1px solid var(--line);
  font-size: 12px;
}
.badge.warn { background: var(--premium-bg); color: var(--premium); border-color: transparent; }
.capacity { display: flex; gap: 10px; flex-wrap: wrap; max-width: 780px; margin: 0 auto calc(var(--bar) + 24px); padding: 0 16px; color: var(--ink-3); font-size: 12px; font-variant-numeric: tabular-nums; }
/* Which app.js is actually live. Three uploads in a row looked unchanged because the file
   had not landed, and there was no way to tell from the page itself. */
.capacity .build { margin-left: auto; opacity: 0.75; }
.capacity > * + *::before { content: "·"; margin-right: 10px; }
.recommended { margin-left: 6px; font-weight: 400; font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--accent-text); }

main { max-width: 880px; margin: 0 auto; padding: 24px 16px calc(var(--bar) + 32px); }

.card {
  background: var(--surface);
  border-radius: var(--radius);
  padding: var(--card-pad);
  margin-bottom: 20px;
}
.card.wide { max-width: none; }

h1 { font-size: 24px; margin: 0 0 4px; letter-spacing: -0.02em; line-height:80% }
h2 { font-size: 19px; margin: 0; letter-spacing: -0.01em; }
h3 { font-size: 14px; margin: 22px 0 8px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-3); }
.lede { color: var(--ink-2); margin: 0 0 22px; }
.count { color: var(--ink-3); font-weight: 400; font-size: 13px; }

/* The title takes the line, so the icons are pushed right without a margin trick, and a hint
   belongs under the title rather than between it and the bin — which is what used to drop the
   bin onto a line of its own, at the left, as soon as the screen was narrow. */
.section-head { display: flex; align-items: center; gap: 8px 12px; flex-wrap: wrap; }
.section-head > :first-child { flex: 1 1 auto; min-width: 0; }
.section-head > .icon, .section-head > .tray-actions { flex: none; order: 1; }
.section-head > .hint { order: 2; flex: 1 0 100%; margin: 0; }

/* ACCORDIONS: a submitted step becomes one line you can reopen. The drawer shows what was
   decided; the pencil is the only way back into the form, so a curious tap cannot edit. */
.card-head-row { display:flex; align-items:center; gap:8px; }
.card-head { display:flex; align-items:center; justify-content:space-between; gap:12px; flex:1; min-width:0; text-align:left; padding:0; border:0; background:none; color:inherit; font:inherit; }
.card-head-text { display:flex; align-items:baseline; gap:10px; min-width:0; }
/* The three steps share one heading size, each with its number, so the page reads as a path. */
.card-title { display:flex; align-items:center; margin:0 0 0 -15px; font-weight:700; font-size:27px; letter-spacing:-0.015em; white-space:nowrap; }
.card-title .chev { flex:none; width:10px; margin-right:5px; font-size:11px; color:var(--ink-3); transition:transform .15s; }
.card-title .chev.none { visibility:hidden; }   /* Ideas never folds, but its number still lines up */
.step-n { display:inline-flex; align-items:center; justify-content:center; flex:none; width:25px; height:25px; margin-top:1px; margin-right:8px; border:1px solid var(--line); border-radius:50%; background:var(--accent); color:var(--accent-ink); font-size:12px; font-weight:700; font-variant-numeric:tabular-nums; }
.card-summary { color:var(--ink-3); font-size:13px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.card-head-row.open .card-summary { display:none; }   /* the drawer below says it in full */
.card-head[aria-expanded="false"] .chev { transform:rotate(-90deg); }
.card-head-row .pencil { flex:none; padding:5px 9px; font-size:13px; line-height:1; opacity:0.6; }
.card-head-row:hover .pencil { opacity:1; }
.card-head-row:not([hidden]) ~ .card-body:not([hidden]) { margin-top:16px; padding-top:16px; border-top:1px solid var(--line); }
/* Once "The Brief" is on screen it names the step, so the greeting that named it before is
   saying the same thing twice. */
.card-head-row:not([hidden]) ~ .card-body > h1, .card-head-row:not([hidden]) ~ .card-body > .lede { display:none; }

/* THE OVERVIEW: what the brief and the thinking settled on, read-only. */
.overview { display:grid; grid-template-columns:auto 1fr; gap:6px 16px; margin:14px 0 0; font-size:14px; }
.overview dt { color:var(--ink-3); font-size:12px; text-transform:uppercase; letter-spacing:0.05em; padding-top:2px; white-space:nowrap; }
.overview dd { margin:0; }
@media (max-width: 560px) { .overview { grid-template-columns:1fr; gap:2px; } .overview dd { margin-bottom:8px; } }

.sub-head { display:flex; align-items:center; gap:8px; width:100%; text-align:left; margin:18px 0 8px; padding:14px 0 0; border:0; border-top:1px solid var(--line); background:none; color:var(--ink-3); font:inherit; font-size:14px; font-weight:600; text-transform:uppercase; letter-spacing:0.06em; }
.sub-head:hover { color:var(--ink); }
.sub-head .chev { transition:transform .15s; font-size:11px; }
.sub-head.closed .chev { transform:rotate(-90deg); }
.sub-head .count { text-transform:none; letter-spacing:0; font-weight:400; }
/* As a card's own header it leads the card, so it drops the rule that separates stacked ones. */
.sub-head.lead { width:auto; flex:1; min-width:0; gap:10px; margin:0; padding:0; border-top:0; color:var(--ink); text-transform:none; letter-spacing:0; }
.sub-head.lead .count { overflow:hidden; text-overflow:ellipsis; }

.sub-body { margin-bottom:18px; }

/* THE SECOND WAY IN: names first, brief inferred from them. */
.shortcut { margin-top:18px; padding-top:16px; border-top:1px solid var(--line); }
.shortcut-body { margin-top:10px; }

.more-row { display:flex; flex-wrap:wrap; justify-content:flex-end; align-items:center; gap:8px; margin-top:16px; }
/* A step's own action sits at the end of it, on the right, where the eye lands last. */
button.action { display:block; margin-left:auto; }

/* The step's own button ends in an arrow that leans forward under the cursor, so the one thing
   on the card you are meant to press also says which way the page is about to go. The bar's
   primary carries it too — Check and Share are the same promise, made from the foot of the
   window. The glyph is a mask over currentColor rather than an image, so it is the button's own
   colour in both themes, at any size, with nothing to fetch. */
button.action::after, .bar-actions button.primary::after { --arrow:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M12 5l7 7-7 7'/%3E%3C/svg%3E"); content:""; display:inline-block; width:1.2em; height:1.2em; margin:-2px 0 0 6px; vertical-align:middle; background-color:currentColor; -webkit-mask:var(--arrow) center/contain no-repeat; mask:var(--arrow) center/contain no-repeat; transition:transform 300ms; }
button.action:hover:not(:disabled)::after, .bar-actions button.primary:hover:not(:disabled)::after { transform:translateX(50%); }

.field { display: block; margin-bottom: 18px; border: 0; padding: 0; font-size: 12px; }
.label { display: block; font-weight: 560; margin-bottom: 3px; }
.hint { display: block; color: var(--ink-3); font-size: 13px; margin-bottom: 7px; }
/* "recommended" beside a label: nothing in the brief is required, so only the fields worth filling are marked. */

input[type=text], input[type=number], textarea {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg);
  color: var(--accent-text);
  font: inherit;
  font-size: 17px;
  resize: vertical;
}
input:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: transparent; }
:is(input, textarea)::placeholder { transition: opacity 0.25s; }
.ph-out::placeholder { opacity: 0; }   /* rotating example placeholders fade between sets */

.row { display: flex; gap: 14px; flex-wrap: wrap; }
.row > .field { flex: 1 1 220px; }

/* A field's own action, pushed to the end of its label rather than over the box, so it can
   never sit on top of what is being typed. Flex rather than a float: a float taller than the
   label line drops into the hint underneath it. */

/* One primary action, and where there is a second way out, the sentence that offers it. */
.submit-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 10px 14px; }
.submit-row > button.action { margin-left: 0; }
.or-skip { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; color: var(--ink-3); font-size: 13px; }
.or-skip button.primary { padding: 11px 26px; background: transparent; color: var(--accent-text); border: 1px solid var(--accent); }
.or-skip button.primary:hover:not(:disabled) { background: var(--accent); color: var(--accent-ink); }

/* BRIEF SLIDES: a first brief pages through its sections; an edit shows them all as one form,
   each under its own heading. The wizard and at-start / at-end classes on the form drive it. */
.slide { min-width:0; margin:0 0 8px; padding:0; border:0; }
.slide-title { padding:0; margin-bottom:12px; font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:0.08em; color:var(--ink-3); }
#briefForm .slide-steps, #briefForm .slide-back, #briefForm .slide-next, #briefForm .slide-skip { display:none; }
#briefForm.wizard .slide:not(.current), #briefForm.wizard .slide-title, #briefForm.wizard:not(.at-end) #brainstormBtn, #briefForm.wizard:not(.at-end) .or-skip { display:none; }
#briefForm.wizard .slide-steps { display:flex; gap:6px; margin:0 0 20px; padding:0; list-style:none; }
	.slide-steps li { flex:1 1 0; min-width:0; }
	.slide-steps button { width:100%; padding:8px 0 0; border:0; border-top:3px solid var(--line); border-radius:0; background:none; color:var(--ink-3); font-size:12px; text-align:left; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
	.slide-steps .done button { border-top-color:var(--ink-3); }
	.slide-steps .current button { border-top-color:var(--accent); color:var(--ink); font-weight:600; }
#briefForm.wizard:not(.at-start) .slide-back { display:inline-block; margin-right:auto; }
#briefForm.wizard:not(.at-end) .slide-next, #briefForm.wizard:not(.at-end) .slide-skip { display:inline-block; }
@media (max-width: 560px) { .slide-steps .current { flex-grow:3; } .slide-steps li:not(.current) button { font-size:0; } }

/* A tone chip past the third is not on offer, but stays readable so the list still reads as ideas. */
.chip-btn:disabled { opacity:0.45; cursor:default; }
.hint.over { color:var(--taken); }

/* THE PROMPT SHEET: a question to take somewhere else, and the instructions for doing it. */
.sheet { width: min(680px, 92vw); padding: 0; border: 1px solid var(--line); border-radius: 14px; background: var(--surface); color: var(--ink); box-shadow: 0 24px 60px rgb(0 0 0 / 0.28); }
.sheet::backdrop { background: rgb(0 0 0 / 0.45); }
.sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 18px 0; }
.sheet-head h2 { margin: 0; font-size: 17px; }
.sheet textarea { display: block; width: calc(100% - 36px); margin: 0 18px; font-family: var(--mono); font-size: 12px; line-height: 1.5; color: var(--ink-2); }
.sheet-foot { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 14px 18px 18px; }
/* The endings a name with none is offered, in the palette's own chips so they read as the same list. */
.pick-endings { padding: 0 18px; max-height: 42vh; overflow-y: auto; }
/* In the palette an unticked chip is retired and is struck through to say so. Here it is simply
   one you have not picked, so it stays a plain choice. */
.pick-endings .kw input:not(:checked) + span { opacity: 1; text-decoration: none; }
.sheet > .hint { margin: 10px 18px 12px; }
.sheet-foot .hint { margin: 0; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip input { position: absolute; opacity: 0; pointer-events: none; }
.chip span {
  display: inline-block;
  padding: 6px 13px;
  border: 1px solid var(--line);
  border-radius: 99px;
  cursor: pointer;
  user-select: none;
  font-size: 14px;
}
.chip input:checked + span { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
.chip input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

.chips.suggest { margin-top: 8px; }
.chip-btn { padding: 4px 11px; border-radius: 99px; font-size: 13px; color: var(--ink-2); background: transparent; }
.chip-btn.on { background: var(--accent); color: var(--accent-ink); border-color: transparent; }

output { font-variant-numeric: tabular-nums; color: var(--ink-2); font-weight: 400; }
input[type=range] { width: 100%; accent-color: var(--accent); margin: 6px 0 0; padding: 0; background: none; }

button {
  font: inherit;
  font-weight: 900;
  padding: 9px 25px;
  border-radius: 28px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--ink);
  cursor: pointer;
}
button:hover:not(:disabled) { border-color: var(--ink-3); }
button:disabled { opacity: 0.5; cursor: not-allowed; }
button.primary { padding: 15px 50px; border-radius: 50px; border-color: transparent; background: var(--accent); color:var(--accent-ink); font-size: 14px; text-transform: uppercase; }
button.ghost { background: transparent; }
button.link { background: none; border: 0; color: var(--accent-text); padding: 0; text-decoration: underline; }

.strategy p { margin: 0 0 10px; color: var(--ink-2); }
.strategy strong { color: var(--ink); }

button.small { padding: 5px 10px; font-size: 12px; }
button.link.small { padding: 4px 0; }

/* THE TWO WAYS IN: one of these is dead weight to you, so you say which before the form loads. */
.mode-pick { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }
.mode { flex: 1 1 240px; display: flex; flex-direction: column; align-items: center; gap: 5px; text-align: center; padding: 22px 18px 18px; border-radius: 12px; border: 1px solid var(--line); background: var(--surface-2); cursor: pointer; }
.mode:hover { border-color: var(--accent); }
.mode-title { font-size: 20px; font-weight: 650; color: var(--ink); }
.mode-sub { font-size: 13px; line-height: 1.45; color: var(--ink-3); font-weight: 400; }
.mode .feature-icon { width:36px; height:36px; padding:0; margin:0 0 8px; background:none; color:var(--ink); transition:transform .2s, color .2s; }   /* the feature cards' drawing, bare and larger, centred over the title */
.mode:hover .feature-icon { transform:scale(1.08); color:var(--accent-text); }   /* the text's colour at rest, the brand's on hover */
.mode-key { transition:color .2s; }
.mode:hover .mode-key { color:var(--accent-text); }   /* the word that names the choice lights with its icon */
.mode-back { margin-bottom: 14px; }

/* LANDING: THE FRONT DOOR'S PITCH UNDER THE STARTER FORM */
.landing { margin:72px 0 0; padding:0 8px; }
.landing > section { margin:0 0 72px; }
.landing h2 { font-size:30px; line-height:1.2; letter-spacing:-0.02em; margin:0 0 12px; }
.landing h3 { margin:0 0 6px; font-size:17px; text-transform:none; letter-spacing:-0.01em; color:var(--ink); }
.landing p { color:var(--ink-2); margin:0 0 12px; }
.landing .eyebrow { margin:0 0 10px; font-size:12px; font-weight:650; text-transform:uppercase; letter-spacing:0.08em; color:var(--accent-text); }
.landing-lede { font-size:18px; line-height:1.55; max-width:62ch; }
.landing-steps, .name-kinds { list-style:none; padding:0; margin:20px 0 0; display:grid; gap:14px; }
.landing-steps { grid-template-columns:repeat(3, 1fr); }
.landing-steps li, .feature, .price-col { background:var(--surface); border-radius:var(--radius); padding:24px; }
.landing-steps .step-n { margin:0 0 14px; }
.landing-steps p, .feature p { margin:0; font-size:14px; }
.name-kinds { grid-template-columns:repeat(auto-fill, minmax(240px, 1fr)); }
.name-kinds li { display:flex; flex-direction:column; gap:3px; padding:16px 18px; border:1px solid var(--line); border-radius:12px; background:var(--surface); font-size:13px; color:var(--ink-3); }
.name-kinds .kind { font-size:11px; font-weight:650; text-transform:uppercase; letter-spacing:0.07em; }
.name-kinds .domain { font:600 21px/1.3 var(--mono); color:var(--ink); }
	.name-kinds .domain b { font-weight:600; color:var(--accent-text); }
.name-kinds .more { border-style:dashed; background:none; }   /* the open end of the list: what the rest of it does not show */
	.name-kinds .more .domain { font-size:16px; color:var(--ink-2); }
.feature-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(250px, 1fr)); gap:14px; margin-top:20px; }
.feature-icon { display:block; box-sizing:content-box; width:30px; height:30px; padding:9px; margin:0 0 14px; border-radius:12px; background:color-mix(in srgb, var(--accent) 16%, transparent); color:var(--accent-text); }
	.feature-icon .fill { fill:currentColor; }
	.feature-icon .ok { fill:var(--available); stroke:none; }   /* the availability answers, in the colours the list keys its rows by */
	.feature-icon .premium { fill:var(--premium); stroke:none; }
	.feature-icon .taken { fill:var(--taken); stroke:none; }
.landing-split { display:grid; grid-template-columns:1fr 1fr; gap:40px; }
	.landing-split h2 { font-size:24px; }
.price-cols { display:grid; grid-template-columns:1fr 1fr; gap:14px; margin-top:20px; }
.price-col ul { margin:0; padding-left:18px; color:var(--ink-2); }
	.price-col li + li { margin-top:4px; }
.price-col:last-child { box-shadow:inset 0 0 0 2px var(--accent); }
.faq details { border-top:1px solid var(--line); padding:14px 0; }
	.faq details:last-child { border-bottom:1px solid var(--line); }
	.faq summary { cursor:pointer; font-weight:600; font-size:16px; }
	.faq details p { margin:10px 0 0; max-width:70ch; }
.landing-cta { text-align:center; }
	.landing-cta h2 { color:var(--accent-text); }   /* the brand yellow in dark; in light, the yellow as text, since #FAD000 on the page is unreadable */
	.landing-cta .mode-pick { max-width:620px; margin:20px auto 0; }
@media (max-width: 560px) {
	.landing { margin-top:48px; padding:0; }
	.landing > section { margin-bottom:56px; }
	.landing h2 { font-size:24px; }
	.landing-lede { font-size:16px; }
	.landing-steps, .landing-split, .price-cols { grid-template-columns:1fr; }
	.landing-split { gap:24px; }
}

/* The slider says nothing; the line under it says everything, so it is sized to be read. */
.range-note { display: block; font-size: 12.5px; color: var(--ink-3); min-height: 17px; }

/* The angle: which direction the name should take, and why. */
.strategy.angle { font-size: 13.5px; margin: 20px 0; padding: 16px 0; border-top:solid 1px var(--line); border-bottom:solid 1px var(--line); line-height: 1.5; color: var(--ink-2); font-style: italic;}

/* WORD GROUPS: colour says what kind of word it is; order says what it is worth. */
/* The groups stack; only the chips inside one flow. As a flex row the container sized each
   group to its content, which left the header's toggle floating mid-row on short groups. */
.kw-groups { display: block; }
.kw-group { margin-top: 12px; --g: var(--ink-3); }
.kw-group.g0 { --g: var(--accent); }
.kw-group.g1 { --g: var(--available); }
.kw-group.g2 { --g: #2a8f8a; }
.kw-group.g3 { --g: var(--premium); }
.kw-group.g4 { --g: var(--forsale); }
.kw-group.g5 { --g: #6b7a99; }
.kw-group.g6 { --g: #8a6ba8; }
.kw-group.g7 { --g: var(--ink-3); }
.kw-group.g8 { --g: var(--ink-3); }
.kw-head { display: flex; align-items: center; gap: 7px; margin-bottom: 7px; font-size: 12px; font-weight: 700; color: var(--ink); text-transform: uppercase; letter-spacing: 0.05em; cursor: pointer; }
.kw-head-label { white-space: nowrap; }
.kw-head input { margin: 0 0 0 auto; accent-color: var(--g); flex: none; cursor: pointer; }
.kw-head .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--g); }
.kw-head .count { font-weight: 400; color: var(--ink-3); text-transform: none; letter-spacing: 0; }
.kw-group .kw-head .dot { background: var(--g); }   /* the group's colour lives in its header alone */
/* What a name from this direction would sound like. Indented under the heading it explains. */
.kw-why { margin: -3px 0 8px 15px; font-size: 12.5px; line-height: 1.45; color: var(--ink-3); }

.keywords { display: flex; flex-wrap: wrap; gap: 7px; }
.kw { position: relative; }
.kw input { position: absolute; opacity: 0; pointer-events: none; }
.kw span {
  display: inline-block;
  padding: 5px 15px;
  border-radius: 99px;
  border: 1px solid var(--line);
  cursor: pointer;
  font-size: 13.5px;
  font-weight: bold;
  background: var(--surface-2);
}
.kw input:checked + span { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
.kw input:not(:checked) + span { opacity: 0.5; text-decoration: line-through; }
.kw input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
.kw span sub { font-size: 9px; opacity: 0.75; margin-left: 5px; vertical-align: baseline; }

/* One badge on every chip: a count of what the word has produced, or that it is untried. */
.kw span sub.badge { display: inline-flex; align-items: center; justify-content: center; margin: -4px -4px 0px 6px; vertical-align: middle; opacity: 1; font-weight: 700; line-height: 1; }
/* A count is outlined, NEW is filled: the one you have to act on is the one that shouts. */
.kw span sub.badge.n { min-width: 17px; height: 17px; padding: 0 4px; border: 1.5px solid currentColor; border-radius: 99px; background: transparent; color: var(--ink); font-size: 10px; font-variant-numeric: tabular-nums; }
.kw span sub.badge.new { height: 16px; padding: 0 6px; border: 1.5px solid var(--ink); border-radius: 99px; background: var(--ink); color: var(--surface); font-size: 7px; letter-spacing: 0.08em; }
.kw input:checked + span sub.badge.n { color: var(--accent-ink); }
.kw input:checked + span sub.badge.new { border-color: var(--accent-ink); background: var(--accent-ink); color: var(--accent); }
/* An ending chip is a place a name can land, not a word, and reads in the mono face endings use elsewhere. */
/* Gold is what an ending looks like in this app — a premium row, a star, a word that doubles
   as a TLD. The endings group took whatever colour its position in the run gave it, which made
   the one group that already had a colour the only one not using it. */
.kw-group.endings { --g: var(--premium-fill); }
.kw.ending span { font-family: var(--mono); font-size: 12.5px; border-color: var(--premium-fill); }
.kw.ending input:checked + span { background: var(--premium-fill); }

/* The last chip in the endings group is a way to add one the model did not think of. It is a
   chip by position rather than by nature, so it takes none of the tick-box styling around it. */
.add-ending-row { margin-top: 8px; }
/* A way to add an ending the model did not think of: a button until it is wanted, then the same
   box-and-Add the words have above it. A bare field with nothing beside it reads as something
   that went wrong rather than something to fill in. */
.add-ending { display: block; }
.add-ending-btn { padding: 5px 12px; border: 1px dashed var(--premium-fill); border-radius: 99px; background: none; color: var(--ink); font: inherit; font-size: 12.5px; font-weight: 600; }
.add-ending-btn:hover { background: var(--premium-fill); color: var(--accent-ink); border-style: solid; }
.add-ending-form { margin-top: 0; align-items: center; }
.add-ending-form input { flex: 1; min-width: 0; font-family: var(--mono); font-size: 15px; }
.add-ending-form input:focus { outline: 2px solid var(--premium-fill); outline-offset: -1px; border-color: transparent; }

/* A word that is also an ending is worth more than one that is not, and is dressed to say so. */
.kw.tld span { border-style: dashed; border-color: var(--premium-fill); }
.kw.tld span sub.is-tld { font-family: var(--mono); font-size: 10px; opacity: 1;  font-weight:bolder; background:#0002; padding:0 2px;}
.kw.tld input:checked + span { background: var(--premium-fill); }
.kw.tld input:checked + span sub.is-tld { color: inherit; }

.add-keyword { display: flex; gap: 8px; margin-top: 12px; align-items: flex-end; }
.add-keyword textarea { flex: 1; min-height: 52px; font-size: 14px; }

.add-domains-row { display:flex; gap:8px; align-items:flex-end; }
.add-domains-row textarea { flex:1; font-family: var(--mono); font-size: 14px; min-height: 62px; }

/* THE POOL TOOLBAR: two controls, each folding into a button of its own, and only one of them
   open at a time. Searching is what you reach for when you know what you are looking for, so it
   holds the line by default and the tabs stay folded into the button beside it.

   It sticks to the top of the window once the list scrolls past, because the list is long and a
   search you have to scroll back up to reach is one you do not use. Its background is the card's
   own, so the rows pass underneath it rather than through it. */
/* Stuck to the top it is the window's toolbar, so it spreads the whole way across and pads
   itself back in line with the card's contents. Off the top edge it is the card's again. */
.pool-bar.stuck { width:calc(100vw - var(--side)); max-width:calc(100vw - var(--side)); margin-inline:calc(50% - (100vw - var(--side)) / 2); padding-inline:max(16px, calc((100vw - var(--side)) / 2 - 424px + var(--card-pad))); box-shadow:0 6px 18px rgb(0 0 0 / 0.10); }
.pool-bar { position:sticky; top:0; z-index:4; display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin:14px 0 0; padding:10px 0; border-bottom:1px solid var(--line); background:var(--surface); }
/* DESKTOP, STUCK: two rows of chips pinned over the list reads as cramped, so once stuck the bar
   sizes to its contents and, when that is wider than the card, hangs out past both its edges,
   centred on it, up to 16px short of the window. Only a window too narrow even for that wraps.
   The strip, line and shadow move to ::before so they can still span the whole window. While it
   fits it lines up with the card's contents exactly as it does in the flow, so nothing moves. */
@media (min-width: 561px) {
	.pool-bar.stuck { flex-wrap:nowrap; width:max-content; min-width:100%; max-width:calc(100vw - var(--side) - 32px); margin-inline:50% 0; padding-inline:0; transform:translateX(-50%); border-bottom:0; background:none; box-shadow:none; }
	.pool-bar.stuck::before { content:""; position:absolute; z-index:-1; top:0; bottom:0; left:calc(50% - (100vw - var(--side)) / 2); right:calc(50% - (100vw - var(--side)) / 2); border-bottom:1px solid var(--line); background:var(--surface); box-shadow:0 6px 18px rgb(0 0 0 / 0.10); }
}
/* Wide enough to think in while it has the focus; once it does not, down to the width of what
   it holds, so the line goes back to the chips. --chars is set from the query by app.js. */
/* An icon's worth of box until it is wanted, then a third of the window while it is being typed
   into: nothing on the line moves over for a search nobody is using. Left holding a query it
   settles to the width of that query — visible, because a filter you cannot see is one you
   forget is on, but no wider than what it is holding. */
.pool-search { display:flex; flex:none; width:42px; cursor:text; align-items:center; gap:5px; min-width:0; overflow:hidden; padding:0 6px 0 11px; border:1px solid var(--line); border-radius:8px; background:var(--surface-2); transition:width 140ms ease; }
.pool-search:focus-within { width:30vw; min-width:180px; max-width:100%; }
.pool-search.settled { width:auto; flex:0 0 auto; min-width:0; }
.pool-search.settled input { width:calc(var(--chars, 8) * 1ch + 2ch); flex:none; }
.pool-search svg { flex:none; color:var(--ink); }   /* folded, the icon IS the control — grey reads as disabled */
.pool-search input { flex:1; min-width:0; padding:6px 0; border:0; background:none; color:var(--ink); font:inherit; font-size:15px; font-weight:bolder;}
/* A filter you cannot see is one you forget is on, and at 15px on a busy toolbar this one was
   missed. Holding a query the text goes up to 20px; the padding comes off by as much as the
   taller line adds, so the bar it sits in does not move. */
.pool-search.filtering input { padding-block:3px; font-size:20px; }
.pool-search input:focus { outline:none; }
.pool-search:focus-within { border-color:var(--accent); }
.pool-search input::-webkit-search-cancel-button { display:none; }   /* the app's own clear sits beside the count, so the browser's would be a second one */
.pool-search .found { flex:none; margin-left:-2px; color:var(--ink-3); font-size:12px; font-variant-numeric:tabular-nums; }
.pool-search .ghost.icon { flex:none; padding:2px 6px; border:0; color:var(--ink-3); font-size:12px; }

/* A folded control still names what it holds: the search carries whatever was typed, and the
   filter carries the kind in force, so nothing hides behind the word "Filter". */

/* KIND CHIPS: one grouping the rows actually carry, filtered server-side so the counts are real.
   Unfolded, they take the rest of the toolbar line and wrap within it. */
.tabs { display:flex; gap:4px; flex-wrap:wrap; }
.pool-bar .tabs { flex:1 1 260px; min-width:0; }
.toggle { display:inline-flex; align-items:center; gap:6px; font-size:13px; color:var(--ink-2); white-space:nowrap; cursor:pointer; }
.toggle input { margin:0; accent-color:var(--accent); }
.tab { display:inline-flex; align-items:center; gap:6px; padding:6px 11px; border:1px solid transparent; border-radius:99px; background:none; color:var(--ink-2); font-size:13px; }
.tab:hover { background:var(--surface-2); border-color:transparent; }
.tab.on { background:var(--accent); color:var(--accent-ink); }
.tab .n { font-size:11px; opacity:0.75; font-variant-numeric:tabular-nums; }

/* The status row rides in the bar that sticks, because it is the filter people reach for and
   it carries the colours the old key used to explain — whether you can buy a name is asked all
   the way down a long list, while what kind of name it is gets asked once in a while. Square,
   so it reads as a different order of control from the pills below it. Each tab tints from one variable, so the selected state can flip the
   label to a contrasting ink instead of inheriting the colour it sits on. */
#kindTabs { margin:10px 0 0; }
.tabs.status { --tint:var(--ink-2); --tint-bg:var(--surface-2); }   /* the defaults live here, so a tab's own class can win */
.tabs.status .tab { padding:8px 14px; border-radius:6px; border-color:var(--line); font-size:13.5px; font-weight:560; color:var(--tint); }
.tabs.status .tab::before { content:""; flex:none; width:8px; height:8px; border-radius:2px; background:var(--tint); }
.tabs.status .tab:hover { background:var(--surface-2); border-color:var(--tint); }
/* Selected, a tab wears the same two colours as the rows it filters to, so the tab and the
   list read as one thing rather than two colour schemes for the same status. */
.tabs.status .tab.on { background:var(--tint-bg); border-color:var(--tint); padding-left:11px; color:var(--tint); font-weight:650; }
.tabs.status .tab:first-child { --tint:var(--accent-text); }
.tabs.status .tab:first-child::before { display:none; }
/* The shortlist is not an answer from the registrar, so it wears the star it is made of rather
   than the coloured square the answers share. */
.tabs.status .tab.s-new { --tint:var(--accent-text); --tint-bg:var(--surface-2); }
.tabs.status .tab.s-starred { --tint:var(--premium); --tint-bg:var(--premium-bg); }
.tabs.status .tab.s-starred::before { content:"\2605"; width:auto; height:auto; background:none; color:var(--tint); font-size:12px; line-height:1; }
.tabs.status .tab.s-available { --tint:var(--available); --tint-bg:var(--available-bg); }
.tabs.status .tab.s-premium { --tint:var(--premium); --tint-bg:var(--premium-fill); }
.tabs.status .tab.s-premium.on { --tint:var(--premium-strong); }
.tabs.status .tab.s-for_sale { --tint:var(--forsale); --tint-bg:var(--forsale-bg); }
.tabs.status .tab.s-taken { --tint:var(--taken); --tint-bg:var(--taken-bg); }
.tabs.status .tab.s-unknown { --tint:var(--unknown); --tint-bg:var(--unknown-bg); }
.tabs.status .tab.s-unchecked { --tint:var(--ink-2); --tint-bg:var(--surface-2); }

/* DIRECTION TABS: one per story in the project, at the top of the palette card since the palette
   and the list below are whichever tab is on. A tab is a div so the pencil and the bin can sit
   inside it; the name is the button. A dot says the brief moved under its words, a dashed edge
   that it has none yet, and the ring that it is being brainstormed now. */
.tabs.directions { margin:0 0 14px; gap:6px; }
.tab.dir { padding:0 3px 0 0; gap:0; border-color:transparent; }
.tab.dir .tab-name { display:inline-flex; align-items:center; gap:6px; padding:6px 11px; border:0; border-radius:99px; background:none; color:inherit; font:inherit; font-size:13px; font-weight:560; cursor:pointer; }
.tab.dir.on { background:var(--accent); color:var(--accent-ink); }
.tab.dir.on .tab-name { font-weight:650; }
.tab.dir.empty { border:1px dashed var(--line); color:var(--ink-3); }
.tab.dir.empty.on { border-color:transparent; color:var(--accent-ink); }
.tab.dir.stale .tab-name::after { content:""; width:7px; height:7px; border-radius:50%; background:var(--taken); }
.tab.dir.busy .tab-name::after { content:""; width:11px; height:11px; border:2px solid currentColor; border-right-color:transparent; border-radius:50%; animation:spin 0.7s linear infinite; }
.tab.dir .side-act { width:24px; height:24px; color:inherit; opacity:0.75; }
.tab.dir .side-act:hover { background:rgb(0 0 0 / 0.12); color:inherit; opacity:1; }
.tab.dir .side-rename { margin:2px 4px; padding:4px 8px; font-size:13px; width:140px; }
.tab.add { border:1px dashed var(--line); color:var(--ink-3); }
.tab.add:hover { border-color:var(--ink-3); color:var(--ink); }

/* What the open tab is about, above the words: the story on two lines (the whole of it on
   hover), and chips for anything it says differently from the brief. */
.direction-head { display:flex; align-items:flex-start; gap:10px; margin:0 0 14px; padding:12px 14px; border-radius:10px; background:var(--surface-2); }
.direction-text { flex:1; min-width:0; }
.direction-story { margin:0; font-size:14px; line-height:1.45; color:var(--ink-2); display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.direction-story:empty { display:none; }
.direction-overrides { display:flex; flex-wrap:wrap; gap:6px; margin:8px 0 0; }
.direction-overrides .chip-btn { cursor:default; }
.direction-story:empty + .direction-overrides { margin-top:0; }
.direction-empty { margin:4px 0 14px; color:var(--ink-2); font-size:14px; }
.stale-note { display:flex; align-items:center; justify-content:space-between; gap:10px; margin:0 0 14px; padding:10px 14px; border-radius:10px; background:var(--premium-bg); color:var(--premium); font-size:13.5px; }
.stale-note button { flex:none; padding:5px 14px; font-size:13px; }
.results-for { margin-left:8px; font-size:15px; font-weight:400; color:var(--ink-3); }
.results-for:empty { display:none; }

/* The sheet that adds or edits a direction: the brief's own fields, inside the dialog's gutter. */
.sheet-form { padding:6px 18px 0; }
.sheet-form .sheet-foot { padding-inline:0; }
.sheet-form .field { margin-bottom:16px; }
.sheet-form textarea, .sheet-form input[type=text] { width:100%; }
.adjust { margin:0 0 4px; }
.adjust summary { cursor:pointer; padding:4px 0 12px; color:var(--ink-2); font-size:13.5px; font-weight:560; }
.adjust summary:hover { color:var(--ink); }
.adjust[open] summary { padding-bottom:14px; }

/* Which directions to brainstorm: one row each, ticked, with its price; the button adds them up. */
.split-list { max-height:50vh; overflow-y:auto; padding:0 18px; }
.split-row { display:grid; grid-template-columns:auto 1fr auto; gap:12px; align-items:start; padding:12px 0; border-top:1px solid var(--line); cursor:pointer; }
.split-row:first-child { border-top:0; }
.split-row input { margin:4px 0 0; accent-color:var(--accent); }
.split-text { min-width:0; }
.split-text b { display:block; font-size:14px; }
.split-text p { margin:3px 0 0; font-size:13px; line-height:1.4; color:var(--ink-2); display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.split-cost { font-size:12px; color:var(--ink-3); white-space:nowrap; padding-top:3px; }

/* In the tray, which tab a kept name is on; from another tab it is the way there. */
.dir-chip { padding:1px 8px; border:1px solid var(--line); border-radius:99px; background:var(--surface-2); color:var(--ink-3); font-size:11px; font-weight:600; cursor:default; }
.dir-chip.jump { cursor:pointer; color:var(--ink-2); }
.dir-chip.jump:hover { border-color:var(--ink-3); color:var(--ink); }

.results { list-style: none; margin: 16px 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }

/* A variation sits under the idea it came from, set in from the edge to read as one family. */
.result.variant { margin-left:22px; }
.result.variant::before { content:"↳"; position:absolute; left:-18px; top:12px; color:var(--ink-3); font-size:13px; }
.result.variant .name { font-size:15px; }
.result .buttons .variations { color:var(--accent-text); }
.result .buttons .variations.open { background:var(--surface); color:var(--ink); border-color:var(--ink-3); }

.result {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-areas:
    "star name    remove"
    "star meta    buttons";
  gap: 2px 12px;
  align-items: center;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-left: 4px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
}
.result.unchecked { border-left-color: var(--line); }
.result.available { border-left-color: var(--available); background: var(--available-bg); }
.result.premium { border-left-color: var(--premium); background: var(--premium-bg); }
.result.for_sale { border-left-color: var(--forsale); background: var(--forsale-bg); }
.result.taken { border-left-color: var(--taken); background: var(--taken-bg); opacity: 0.5; }
.result.taken:hover, .result.taken:focus-within { opacity: 0.85; }
.result.unknown, .result.unsupported { border-left-color: var(--unknown); background: var(--unknown-bg); }
/* In the list the kept rows are picked out by an amber edge. Not in the shortlist: every row
   there is kept, so the edge would say nothing and would hide the answer it is there to show. */
#results .result.starred { border-left-color: var(--premium); }
.result.leaving { opacity: 0; transform: translateX(-12px); transition: opacity .18s, transform .18s; }

.result > .star {
  grid-area: star;
  font-size: 19px;
  line-height: 1;
  padding: 6px 8px;
  border: 0;
  background: none;
  color: var(--ink-3);
  border-radius: 6px;
}
.result > .star:hover { color: var(--premium); background: var(--surface-2); }
.result > .star.on { color: var(--premium); }
.result > .star:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.result .name { grid-area: name; font-family: var(--mono); font-size: 17px; font-weight: 550; width: 100%; padding: 2px 6px; margin: -2px -6px; border: 1px solid transparent; border-radius: 6px; background: transparent; color: inherit; }
.result input.name:hover { border-color: var(--line); }
.result input.name:focus { outline: none; border-color: var(--accent); background: var(--surface); }
.result.taken .name { color: var(--ink-3); }
/* min-width:0 because a grid item will not shrink below its content otherwise, and a long note
   pushed the whole middle column — and the row with it — wider than the list. */
.result .meta { grid-area: meta; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; min-width: 0; font-size: 12.5px; color: var(--ink-2); }
.result .pill { font-weight: 600; font-size: 12px; }
.result.available .pill { color: var(--available); }
.result.premium .pill { color: var(--premium); }
.result.for_sale .pill { color: var(--forsale); }
.result.taken .pill { color: var(--taken); }
.result.unknown .pill, .result.unsupported .pill { color: var(--unknown); }
.result .price { font-variant-numeric: tabular-nums; }
.result .price .renews { color:var(--premium); }   /* a renewal well above the first year, said beside it */
.result .note[title] { border-bottom: 1px dotted currentColor; cursor: help; }
.result .note { color: var(--ink-3); }
.result .resale-wait { color: var(--ink-3); display: inline-flex; align-items: center; }
.result .resale-wait::after { width: 8px; height: 8px; margin: 0; border-width: 1.5px; }
/* The note sits where the word chips used to: one line of it, as much as the row can show,
   and the whole thing on hover. Empty, it is an invitation rather than a blank. */
/* Shrinkable, which takes flex-shrink AND min-width:0: a flex item will not go below its own
   content width without both, so the ellipsis never got a chance and the line ran off the row. */
.note-tag { flex: 0 1 auto; min-width: 0; max-width: 46ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 1px 7px; border: 1px dashed transparent; border-radius: 99px; background: none; color: var(--ink-2); font: inherit; font-size: 11.5px; text-align: left; cursor: text; }
.note-tag:hover { border-color: var(--ink-3); color: var(--ink); }
/* Your own words wear the chip; the model's reason sits plain, so which is which needs no
   label. Until either exists the slot is an invitation, and only on the row under the cursor. */
.note-tag.mine { border-color: var(--line); }
.note-tag.theirs { color: var(--ink-3); }
.note-tag.empty { color: var(--ink-3); opacity: 0; transition: opacity .12s; }
.result:hover .note-tag.empty, .result:focus-within .note-tag.empty, .result.starred .note-tag.empty { opacity: 1; }
.note-field { flex: 1 1 auto; min-width: 0; max-width: 46ch; padding: 4px 7px; border: 1px solid var(--accent); border-radius: 8px; background: var(--surface); color: var(--ink); font: inherit; font-size: 12.5px; resize: vertical; }
.note-field:focus { outline: none; }

.result .buttons { grid-area: buttons; display: flex; gap: 4px; align-items: center; }
.result .buttons a, .result .buttons button {
  padding: 5px 9px;
  font-size: 12.5px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink-2);
  text-decoration: none;
  cursor: pointer;
  line-height: 1.4;
}
/* The two that are a glyph rather than a word: a price tag to buy, a pencil to annotate. The
   word "Register" was the widest thing in the row and said less than the symbol does. */
.result .buttons .buy { color: var(--available); border-color: var(--available); font-weight: 700; padding-inline: 10px; }
.result .buttons .buy:hover { background: var(--available-bg); color: var(--available); }
.result .buttons .note-btn { padding-inline: 8px; }
/* A mark rather than a word — the tag, and the globe that stands for Visit — centred on the line
   the words either side of it sit on, so a row of mixed buttons is still one height. */
.result .buttons .visit { padding-inline: 8px; }
.result .buttons svg { vertical-align: middle; }
/* The actions are for the row being looked at, so they come up on the row under the pointer and
   stay out of the way on the rest: three hundred rows of buttons was a wall to read the names
   through. One rule for the list and the shortlist alike, since both draw the same .result row.
   They keep their room while hidden, so nothing moves when they appear; they show for the
   keyboard too; and the one whose menu is open stays lit, since the pointer has gone into the
   menu it hangs off. Only where there is a pointer that can hover: a phone never hides them. */
@media (hover: hover) {
  .result .buttons > * { opacity: 0; transition: opacity 120ms ease; }
  .result:hover .buttons > *, .result:focus-within .buttons > *, .result .buttons > .open { opacity: 1; }
}
.result .buttons .enquire { color: var(--forsale); border-color: var(--forsale); font-weight: 700; padding-inline: 10px; }
.result .buttons .enquire:hover { background: var(--forsale-bg); color: var(--forsale); }
/* How crowded the name already is, next to the answer from the registrar: both are answers about
   the name rather than things to do with it, so they read together and wear the same colours. */
.result .meta .noise { --tint: var(--available); --tint-bg: var(--available-bg); display: inline-flex; align-items: center; gap: 0; padding: 1px 9px 1px 6px; border: 1px solid var(--tint); border-radius: 99px; background: var(--tint-bg); color: var(--tint); font: inherit; font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; cursor: pointer; }
.result .meta .noise.n-low { --tint: var(--available); --tint-bg: var(--available-bg); }
.result .meta .noise.n-mid { --tint: var(--premium); --tint-bg: var(--premium-bg); }
.result .meta .noise.n-high { --tint: var(--taken); --tint-bg: var(--taken-bg); }
.result .meta .noise:hover, .result .meta .noise[aria-expanded="true"] { border-color: var(--ink-3); }
/* What is out there, on its own line under the answer: a paragraph does not belong on a meta strip. */
.noise-detail { flex: 1 1 100%; margin-top: 4px; padding: 6px 9px; border-left: 3px solid var(--line); background: var(--surface-2); color: var(--ink-2); font-size: 12.5px; line-height: 1.45; }
/* Centred and in the accent, like the Check button it sits under: both are the one thing left
   to do with a list you have got this far with, so they are the same offer twice. */
.tray-foot { display: flex; justify-content: center; margin-top: 14px; }
/* The same signal the scores wear, so the button and what it produces read as one thing. A mask
   over currentColor rather than a child element: the busy state rewrites the button's text, and
   a mark inside it would be thrown away the first time it was pressed. */
#noiseBtn::before { --signal:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='5' cy='12' r='1.4' fill='black' stroke='none'/%3E%3Cpath d='M7.9 8.6 A4.5 4.5 0 0 1 7.9 15.4'/%3E%3Cpath d='M10.1 5.9 A8 8 0 0 1 10.1 18.1'/%3E%3Cpath d='M12.4 3.2 A11.5 11.5 0 0 1 12.4 20.8'/%3E%3C/svg%3E"); content:""; display:inline-block; width:1.15em; height:1.15em; margin:-2px 8px 0 0; vertical-align:middle; background-color:currentColor; -webkit-mask:var(--signal) center/contain no-repeat; mask:var(--signal) center/contain no-repeat; }
/* Looking a name up is a question you have before deciding whether to keep it, not after, so
   every row carries it — it used to appear only once a name was starred, which is back to front. */
.result .buttons a:hover, .result .buttons button:hover { border-color: var(--ink-3); color: var(--ink); }
/* In the corner opposite the name, not at the end of the actions: it is the one button on the
   row that undoes rather than does, and it sat against the one that registers. */
.result > .remove { grid-area: remove; justify-self: end; align-self: start; padding: 4px 8px; border: 1px solid transparent; border-radius: 6px; background: none; color: var(--ink-3); font-size: 12.5px; line-height: 1.2; }
.result > .remove:hover { color: var(--taken); border-color: var(--taken); }

/* THE ENDINGS MENU: one list, positioned in viewport coordinates under whichever box has the
   caret, so no card, tray or fixed bar can clip it. Above the status bar, below the toasts. */
.tld-menu { position:fixed; z-index:25; max-height:min(46vh, 320px); overflow-y:auto; margin:0; padding:4px; list-style:none; border:1px solid var(--line); border-radius:10px; background:var(--surface); box-shadow:0 8px 28px rgb(0 0 0 / 0.16); }
.tld-opt { display:flex; align-items:baseline; gap:8px; padding:6px 9px; border-radius:6px; cursor:pointer; font-size:13.5px; }
.tld-opt .tld { font-family:var(--mono); font-weight:600; }
/* The business's own endings carry the line the brainstorm gave for them; the rest carry nothing,
   which is how you tell at a glance which ones were chosen for you. */
.tld-opt .why { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--ink-3); font-size:12px; }
.tld-opt.on, .tld-opt:hover { background:var(--accent); color:var(--accent-ink); }

/* The variations menu is the endings menu with room for a reason and a state per row. */
/* A min-width so the menu does not open a few pixels wide around the spinner and then jump
   out to full width the moment the names land. */
.vary-menu { min-width:min(88vw, 250px); max-width:min(92vw, 340px); max-height:min(58vh, 430px, var(--room, 100vh)); padding-top:22px; }
/* The close sits over the list rather than in it, so scrolling the names does not scroll the
   way out off the top. Same corner and same shape as the drawers use, a size down: the space it
   reserves above the first name is space the last idea's menu needs at the foot of the screen. */
.vary-menu .tray-close { position:sticky; top:-4px; float:right; margin:-20px -1px 0 0; width:22px; height:22px; font-size:11px; }

/* Sits under the menu and over everything else, so a tap meant to dismiss lands on nothing.
   Transparent on a pointer, where an accidental click is a small cost and dimming the page for
   a dropdown is heavy-handed. */
.vary-backdrop { position:fixed; inset:0; z-index:24; background:transparent; }

/* On a phone it becomes a sheet at the foot of the screen. Anchored to the button it opened
   from, it sat directly under that row's delete button — so the thing nearest the menu, where a
   close control belongs, was the one that throws the idea away. Down here it is nowhere near
   it, and the backdrop dims what it is covering so the sheet reads as the only thing in play. */
@media (max-width: 560px) {
  .vary-backdrop { background:rgb(0 0 0 / 0.38); }
  /* Both edges pinned, or it is sized by its content and hangs off the left: anchored only to
     the right, a long name plus its reason is wider than the screen and goes over the edge. */
  .vary-menu { left:0; right:0; bottom:0; top:auto; width:auto; min-width:0; max-width:none; max-height:72vh; padding:26px 8px calc(8px + env(safe-area-inset-bottom, 0px)); border-width:1px 0 0; border-radius:14px 14px 0 0; box-shadow:0 -10px 34px rgb(0 0 0 / 0.26); }
  .vary-opt .name { overflow:hidden; text-overflow:ellipsis; }
  .vary-opt, .vary-own-btn { padding-block:11px; }
  .vary-opt .mark { font-size:20px; }
}
/* The founder's own labels. A tag says nothing to the app, so it is drawn as plain text rather
   than in the colours the app's own answers wear — the row already has enough of those. */
.tag-menu { min-width:min(90vw, 230px); max-width:min(92vw, 300px); max-height:min(52vh, 360px, var(--room, 100vh)); padding:5px; }
.tag-opt { display:flex; align-items:center; gap:8px; padding:6px 9px; border-radius:6px; cursor:pointer; font-size:13.5px; }
.tag-opt:hover { background:var(--surface-2); }
.tag-opt .mark { flex:none; width:1.1em; text-align:center; font-weight:700; color:var(--accent-text); }
.tag-opt .label { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tag-opt .n { flex:none; color:var(--ink-3); font-size:11.5px; font-variant-numeric:tabular-nums; }
/* The three marks that act on a tag itself, shown on the row under the pointer or the keyboard
   only: a column of bins down every row reads as a list about to be emptied. They keep their room
   while hidden, so nothing shifts when they appear. Where there is no pointer to hover with they
   are always there, or a phone could never reach them at all. */
.tag-opt .tag-act { flex:none; display:inline-flex; align-items:center; justify-content:center; width:24px; height:24px; padding:0; border:0; border-radius:5px; background:none; color:var(--ink-3); cursor:pointer; }
.tag-opt .tag-act:hover { background:var(--surface); color:var(--ink); }
.tag-opt .tag-act.bin:hover { color:var(--taken); }
@media (hover: hover) {
  .tag-opt .tag-act { opacity:0; }
  .tag-opt:hover .tag-act, .tag-opt:focus-within .tag-act { opacity:1; }
}
.tag-rename { flex:1; min-width:0; padding:3px 6px; border:1px solid var(--accent); border-radius:5px; background:var(--bg); color:var(--ink); font:inherit; font-size:13px; }
.tag-rename:focus { outline:none; }
.tag-new { display:flex; gap:6px; align-items:center; margin-top:4px; padding-top:5px; border-top:1px solid var(--line); }
.tag-new input { flex:1; min-width:0; padding:5px 8px; border:1px solid var(--line); border-radius:6px; background:var(--bg); color:var(--ink); font:inherit; font-size:13px; }
.tag-new input:focus { outline:2px solid var(--accent); outline-offset:-1px; border-color:transparent; }
.tag-new button { flex:none; padding:5px 11px; border-radius:6px; font-size:12.5px; font-weight:700; }
/* On a row, a tag is a quiet chip in the meta strip: it is something you wrote, not an answer. */
.result .meta .tag { padding:1px 8px; border:1px solid var(--line); border-radius:99px; color:var(--ink-2); font-size:11.5px; }
.result .buttons .tag-btn { padding-inline:7px; }
.result .buttons .tag-btn.on { color:var(--accent-text); border-color:var(--accent); }

.vary-none { padding:8px 9px; color:var(--ink-3); font-size:12.5px; }
/* Room around the turning, and centred: the margin that separates it from a label is wrong
   when it is the only thing there. */
.vary-wait { display:flex; align-items:center; justify-content:center; padding:26px 9px; color:var(--ink-3); }
.vary-wait::after { margin-left:0; width:17px; height:17px; }
.vary-opt { display:flex; align-items:center; gap:8px; padding:6px 9px; border-radius:6px; cursor:pointer; font-size:13.5px; }
.vary-opt .name { font-family:var(--mono); font-weight:600; white-space:nowrap; }
.vary-opt .why { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--ink-3); font-size:12px; }
.vary-opt .mark { flex:none; width:1.25em; text-align:center; font-size:17px; line-height:1; font-weight:700; color:var(--ink-3); }
.vary-opt:hover:not(.added) { background:var(--accent); color:var(--accent-ink); }
.vary-opt:hover:not(.added) .why { color:inherit; opacity:0.8; }
.vary-opt.added { cursor:default; opacity:0.55; }
.vary-opt.added .mark { color:var(--available); }

/* A name already in the list wears its answer, so the menu says at a glance which endings are
   covered and how they went — the same colours the list and the tabs use. */
.vary-opt.have { --tint:var(--ink-3); }
.vary-opt.have .name, .vary-opt.have .mark { color:var(--tint); }
.vary-opt.have .why { color:var(--tint); opacity:0.85; }
.vary-opt.have:hover { background:var(--surface-2); }
.vary-opt.have:hover .why { color:var(--tint); opacity:0.85; }
.vary-opt.s-available { --tint:var(--available); }
.vary-opt.s-premium { --tint:var(--premium); }
.vary-opt.s-for_sale { --tint:var(--forsale); }
.vary-opt.s-taken { --tint:var(--taken); }
.vary-opt.s-unknown, .vary-opt.s-unsupported { --tint:var(--unknown); }
.vary-opt.s-unchecked { --tint:var(--ink-3); }

/* The last row: a way to type the name nothing above quite is. */
.vary-own { margin-top:4px; padding-top:4px; border-top:1px solid var(--line); display:flex; gap:6px; align-items:center; }
.vary-own-btn { width:100%; padding:6px 9px; border:0; border-radius:6px; background:none; color:var(--accent-text); font:inherit; font-size:13px; font-weight:600; text-align:left; cursor:pointer; }
.vary-own-btn:hover { background:var(--surface-2); }
.vary-own-field { flex:1; min-width:0; padding:5px 8px; border:1px solid var(--line); border-radius:6px; background:var(--bg); color:var(--accent-text); font-family:var(--mono); font-size:13.5px; }
.vary-own-field:focus { outline:2px solid var(--accent); outline-offset:-1px; border-color:transparent; }
.vary-own-go { flex:none; padding:5px 12px; border-radius:6px; font-size:12.5px; font-weight:700; }
/* The one model call in the menu, offered after the free ones, so it reads as the next step rather than the first. */
.vary-remix { margin-top:4px; padding-top:4px; border-top:1px solid var(--line); }
.vary-remix-btn { width:100%; padding:6px 9px; border:0; border-radius:6px; background:none; color:var(--accent-text); font:inherit; font-size:13px; font-weight:600; text-align:left; cursor:pointer; }
.vary-remix-btn:hover { background:var(--surface-2); }
.vary-opt.remix .mark { color:var(--accent-text); }
.tld-opt.on .why, .tld-opt:hover .why { color:inherit; opacity:0.8; }

/* STATUS BAR: fixed to the foot of the window, so the page count, the errors and the
   actions for whatever you are looking at stay reachable without scrolling back. */
.statusbar { position:fixed; left:var(--side); right:0; transition:left .18s ease; bottom:0; z-index:20; background:var(--surface); border-top:1px solid var(--line); box-shadow:0 -2px 16px rgb(0 0 0 / 0.06); padding:0 16px env(safe-area-inset-bottom, 0px); }
.statusbar-row { display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:nowrap; max-width:880px; margin:0 auto; min-height:47px; padding:10px 0; }
/* The readouts are the part of the bar worth losing: they shrink, clip and finally go, so the
   buttons are never the thing that runs off the side of the screen. */
.statusbar-info { display:flex; align-items:center; gap:10px; flex:0 1 auto; flex-wrap:nowrap; overflow:hidden; font-size:13px; min-width:0; }
.statusbar-info > * { white-space:nowrap; }
/* A dot only where something shows on both sides of it: one before it anywhere along the line, and the very next thing after it. */
.statusbar-info > .sep { display:none; color:var(--ink-3); }
.statusbar-info > :not([hidden]):not(.sep) ~ .sep:has(+ :not([hidden])) { display:inline; }
.statusbar .count { font-size:13px; font-variant-numeric:tabular-nums; }
.statusbar .banner { max-width:880px; margin:10px auto -2px; }


/* SHORTLIST DRAWER: lives below the screen and slides up from behind the bar. The clip is
   what makes it a drawer rather than a panel that appears — it hides the panel until it
   has travelled, and costs no page room while closed. */
.tray-clip { position:absolute; left:0; right:0; bottom:100%; overflow:hidden; max-height:0; pointer-events:none; transition:max-height .24s cubic-bezier(.2,.7,.3,1); }
.tray-clip.open { max-height:min(58vh, 460px); pointer-events:auto; }
.tray { max-height:min(58vh, 460px); overflow-y:auto; background:var(--surface); border-top:1px solid var(--line); box-shadow:0 -8px 28px rgb(0 0 0 / 0.14); transform:translateY(100%); transition:transform .24s cubic-bezier(.2,.7,.3,1); }
.tray-clip.open .tray { transform:none; }
.tray-inner { max-width:880px; margin:0 auto; padding:14px 16px 16px; }
.tray-actions { display:flex; gap:6px; align-items:center; }
/* Outside .tray, which is what scrolls: inside it, the way out slid off the top of a long
   drawer the moment you looked down it. Sat in the header's action row it also wrapped into a
   column on a phone, under the button beside it. */
.tray-close { position:absolute; top:10px; right:12px; z-index:3; width:30px; height:30px; display:flex; align-items:center; justify-content:center; padding:0; border:1px solid var(--ink-3); border-radius:50%; background:var(--surface-2); color:var(--ink); font-size:13px; font-weight:700; line-height:1; }
.tray-close:hover { background:var(--ink); border-color:var(--ink); color:var(--surface); }
/* The way out sits over the top-right corner, so the header's own buttons stop short of it
   rather than sliding under it on a screen narrower than the drawer's contents. */
.tray-inner .section-head { padding-right:34px; }

.bar-actions { display:flex; gap:8px; align-items:center; flex:none; flex-wrap:nowrap; }
/* A card's primary is a wide pill; the bar's is a button on a 47px line, at every width. */
.bar-actions button.primary { padding:10px 18px; font-size:13px; }
button.icon { display:inline-flex; align-items:center; justify-content:center; padding:8px 11px; line-height:1; font-size:15px; }
.section-head .icon { padding:6px 8px; color:var(--ink-3); }
button.danger:hover:not(:disabled) { color:var(--taken); border-color:var(--taken); }
button.icon svg { display:block; }
.star-btn { display:flex; align-items:center; gap:5px; font-variant-numeric:tabular-nums; }
.star-btn .star { color:var(--premium); }
.star-btn[aria-expanded="true"] { border-color:var(--ink-3); }
.bar-actions button { padding-block:10px; margin-block:-5px; }   /* a taller tap target, and no wider than it looks */
.bar-pager { display:flex; gap:4px; }
.bar-pager button { padding:8px 12px; font-size:15px; line-height:1; }
button.jump { background:none; border:0; color:var(--ink-2); padding:0; font-size:13px; font-variant-numeric:tabular-nums; }
button.jump:hover:not(:disabled) { color:var(--accent-text); text-decoration:underline; }

.summary { font-size: 13px; color: var(--ink-2); padding: 9px 12px; background: var(--surface-2); border-radius: 8px; margin-bottom: 12px; }
.banner { padding: 11px 14px; border-radius: 8px; margin-bottom: 12px; font-size: 14px; }
.banner.error { background: var(--taken-bg); color: var(--taken); }
.banner.info { background: var(--surface-2); color: var(--ink-2); }


.tray ul { list-style: none; padding: 0; margin: 12px 0 0; display: flex; flex-direction: column; gap: 5px; }

/* The tray draws the list's own row rather than a second design of the same thing, so it needs
   no layout of its own — only to sit tighter, since it is a drawer over the page rather than
   the page. The star at the left edge is what takes a name off the shortlist here. */
/* The name takes the top line to itself, and the answer shares the second with the buttons,
   pushed to the right end of it. The list gives the buttons a column of their own down the
   side; the tray is a drawer and every row of height it saves is another name you can see. */
/* The tray's rows wear their answer the way the list's do. A flat grey set here used to outrank
   every status tint, so a shortlist of free, taken and for-sale names read as one colour. Only
   a row with no answer yet keeps the grey, or it would vanish into the drawer behind it. */
#shortlist .result { grid-template-areas: "star name name" "star meta buttons"; padding: 6px 10px; gap: 0 10px; }
#shortlist .result.unchecked { background: var(--surface-2); }
#shortlist .result .buttons { justify-self: end; }
#shortlist .result > .star { font-size: 16px; padding: 3px 5px; }
#shortlist .result .name { font-size: 14.5px; font-weight: 550; overflow-wrap: anywhere; }
#shortlist .result .meta { font-size: 11.5px; gap: 6px; }
#shortlist .result .pill { font-size: 11.5px; }

/* The tray is where you look at the handful you are choosing between, which is exactly when
   what you thought about each one matters — so the note is read and written here too. The
   pencil is not: the note itself is the way in, and the row has no width to spare. */
#shortlist .result .buttons .note-btn { display: none; }
#shortlist .result .note-tag { font-size: 11px; }
#shortlist .result .note-field { font-size: 12px; }

/* A toast about one name leads with it, set in the face the list uses so the eye finds the
   same string it was just looking for. */
.toast b { font-family: var(--mono); font-weight: 600; }

.toast {
  position: fixed;
  left: calc(var(--side) + (100% - var(--side)) / 2);   /* the middle of the page, not of the window */
  bottom: calc(var(--bar) + 18px);
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--bg);
  padding: 10px 18px;
  border-radius: 99px;
  font-size: 14px;
  z-index: 50;
  box-shadow: 0 6px 24px rgb(0 0 0 / 0.18);
}

/* One spinner, on every button that can be busy. A button whose ::after is already a glyph — the
   step arrow, the bar's primary — kept the glyph and took only the ring's animation, so the arrow
   span in a circle inside a border it had also grown. The busy state owns ::after outright, and
   says so at a specificity those rules cannot beat. */
.spinner::after, button.spinner::after {
  content: "";
  display: inline-block;
  width: 12px;
  height: 12px;
  margin: 0 0 0 8px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  background: none;
  -webkit-mask: none;
  mask: none;
  transform: none;
  animation: spin 0.7s linear infinite;
  vertical-align: -2px;
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (max-width: 560px) {
  main { padding: 16px 10px calc(var(--bar) + 20px); }
  .side-rail.front main{padding-left:25px; padding-right:25px;}
  .statusbar { padding-inline: 10px; }

  /* The lowest-value readouts leave rather than squeeze the buttons off the side. */
  .statusbar-row { gap:8px; }
  /* The word count goes too: the palette it counts is a step up the page, and what is left —
     how much of the list has an answer — is the one number worth the room down here. */
  .statusbar-info #poolCount, .statusbar-info #providerBadge, .statusbar-info #wordsLink, .statusbar-info #endingsLink { display:none; }
  .statusbar-info > .sep { display:none !important; }   /* all that is left is the checked count, so there is nothing to divide; beats the rule that shows a dot */
  /* A toast about a name is usually a sentence with a domain in it, and at a phone's width the
     pill was three words wide and six lines tall. */
  .toast { max-width:85%; }
  .bar-actions { gap:6px; }
  .bar-actions button { padding:8px 11px; font-size:13px; }
  .bar-actions button.primary { padding:9px 13px; }
  /* The star and its number say it; the word is what pushed the bar off the side of the screen. */
  .star-btn span:not(.star) { display:none; }
  /* A heading set for a page is too big for a phone held in one hand. */
  .card-title { font-size:20px; }
  .step-n { width:22px; height:22px; margin-right:7px; }

  /* The filters run past the edge of a phone rather than stacking into a wall of chips, so the
     line stays one line and scrolls. It is the sticky bar itself that scrolls, which is fine —
     only an ANCESTOR with overflow would break the stickiness. */
  .pool-bar { max-width:100%; flex-wrap:nowrap; overflow-x:auto; overflow-y:hidden; scrollbar-width:thin; }
  .pool-bar .tabs { flex:none; flex-wrap:nowrap; }
  .pool-search:focus-within { width:55vw; min-width:0; }
  .bar-pager button { padding:8px 9px; }
  .tray-inner { padding:12px; }
  .card { --card-pad: 30px; padding: var(--card-pad); }   /* room for the chevron left of the step number */
  .history > button { max-width: 118px; }
  /* The discard keeps its corner opposite the name on a phone too. Left out of this template
     it had no cell to sit in, so it was auto-placed into a row of its own at the foot of the
     card — which is the one place a button that throws the idea away should never be. */
  .result {
    margin:0 -10px;
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
      "star name    remove"
      "star meta    meta"
      "buttons buttons buttons";
  }
  .result .buttons { flex-wrap: wrap; margin-top: 6px; }

  .result.variant { margin-left: 14px; }
  .result.variant::before { left: -13px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ACCOUNTS AND CREDITS: all of it hidden on a server with no sign-in and credits off. */
:root { --coin:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='10' fill='%23f2c14e' stroke='%23c9952a' stroke-width='1.6'/%3E%3Ccircle cx='12' cy='12' r='6.2' fill='none' stroke='%23c9952a' stroke-width='1.3'/%3E%3C/svg%3E"); }
.coin { flex:none; vertical-align:-3px; }

/* The price on an AI button, drawn from data-cost so it survives the label being rewritten while
   busy. ::before by default, because .action buttons spend ::after on their arrow; the noise button
   spends ::before on its signal, so its price moves to ::after. */
[data-cost]::before, #noiseBtn[data-cost]::after { content:attr(data-cost); display:inline-block; margin:0 8px 0 0; padding:0 7px 0 21px; border-radius:20px; background:var(--coin) 3px center/15px no-repeat, rgb(0 0 0 / 0.14); color:inherit; font-size:12px; font-weight:700; line-height:20px; letter-spacing:0; text-transform:none; vertical-align:1px; }
#noiseBtn[data-cost]::before { content:""; padding:0; border-radius:0; background-color:currentColor; line-height:inherit; }
#noiseBtn[data-cost]::after { margin:0 0 0 8px; }
button.ghost[data-cost]::before, .vary-remix-btn[data-cost]::before, .price-list li[data-cost]::before { background-color:var(--surface-2); }
.vary-remix-btn[data-cost]::before { float:right; margin:0; }
button.spinner[data-cost]::before { opacity:0.5; }

.credits-chip { display:flex; align-items:center; gap:6px; padding:5px 11px; font-size:13px; font-weight:700; font-variant-numeric:tabular-nums; }
.credits-chip.low { color:var(--taken); }
.account > button { font-weight:600; }
.account-who { display:flex; flex-direction:column; padding:6px 10px 2px; font-size:13px; }
.account-who .hint { margin:0; font-size:12px; overflow:hidden; text-overflow:ellipsis; }

.sheet.narrow { width:min(440px, 92vw); }
.sheet.narrow > p, .sheet.narrow > div:not(.sheet-head):not(.sheet-foot), .sheet.narrow > ul, .sheet.narrow > h3 { margin-left:18px; margin-right:18px; }
.sheet > .hint.small, .hint.small { font-size:12px; }
.sheet-actions { display:flex; gap:10px; }
.sheet-actions .primary { padding:12px 30px; }
.small-head { margin:18px 18px 6px; font-size:13px; font-weight:600; color:var(--ink-2); }
.small-head.flush { margin:20px 0 6px; }   /* inside a card's own padding */

.auth-providers { display:flex; flex-direction:column; gap:10px; margin:6px 18px 14px; }
.auth-btn { width:100%; padding:12px 16px; border-radius:50px; font-weight:600; font-size:14px; }
.auth-btn::before { content:""; display:inline-block; width:18px; height:18px; margin:0 10px 0 0; vertical-align:-4px; background:center/contain no-repeat; }
.auth-google::before { background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath fill='%23FFC107' d='M43.6 20.5H42V20H24v8h11.3C33.7 32.7 29.2 36 24 36c-6.6 0-12-5.4-12-12s5.4-12 12-12c3.1 0 5.8 1.2 7.9 3.1l5.7-5.7C34 6.1 29.3 4 24 4 12.9 4 4 12.9 4 24s8.9 20 20 20 20-8.9 20-20c0-1.3-.1-2.4-.4-3.5z'/%3E%3Cpath fill='%23FF3D00' d='M6.3 14.7l6.6 4.8C14.7 15.1 19 12 24 12c3.1 0 5.8 1.2 7.9 3.1l5.7-5.7C34 6.1 29.3 4 24 4 16.3 4 9.7 8.3 6.3 14.7z'/%3E%3Cpath fill='%234CAF50' d='M24 44c5.2 0 9.9-2 13.4-5.2l-6.2-5.2C29.2 35.1 26.7 36 24 36c-5.2 0-9.6-3.3-11.3-8l-6.5 5C9.5 39.6 16.2 44 24 44z'/%3E%3Cpath fill='%231976D2' d='M43.6 20.5H42V20H24v8h11.3c-.8 2.2-2.2 4.2-4.1 5.6l6.2 5.2C37 39.2 44 34 44 24c0-1.3-.1-2.4-.4-3.5z'/%3E%3C/svg%3E"); }
.auth-microsoft::before { background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 21 21'%3E%3Crect x='1' y='1' width='9' height='9' fill='%23f25022'/%3E%3Crect x='11' y='1' width='9' height='9' fill='%237fba00'/%3E%3Crect x='1' y='11' width='9' height='9' fill='%2300a4ef'/%3E%3Crect x='11' y='11' width='9' height='9' fill='%23ffb900'/%3E%3C/svg%3E"); }
.auth-github::before { background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23181717' d='M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z'/%3E%3C/svg%3E"); }
:root.dark .auth-github::before { filter:invert(1); }

.cost-eg { display:inline-flex; align-items:center; gap:3px; margin:0 2px; font-weight:700; color:var(--ink); white-space:nowrap; }
.model-list { list-style:none; padding:0; margin-top:0; margin-bottom:0; max-height:52vh; overflow-y:auto; border-top:1px solid var(--line); }
.model-list li { display:flex; align-items:center; gap:10px; border-bottom:1px solid var(--line); }
.model-list .radio { flex:1; min-width:0; padding:9px 0; }
.model-list .model-name { flex:1; min-width:0; }
.model-list .model-name small { display:block; color:var(--ink-2); font-size:12px; }
.model-list .model-cost { flex:none; font-size:12px; font-weight:600; color:var(--ink-2); }
.model-list li.locked .radio { opacity:.45; cursor:not-allowed; }
.model-list .model-unlock { flex:none; font-size:12px; padding:4px 10px; }
.setting-row { display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.setting-row.current { display:grid; grid-template-columns:1fr auto; align-items:start; padding:12px 14px; border:1px solid var(--ink); border-radius:10px; }   /* the option in force, outlined, with Change pinned opposite its title however long the description */
.setting-value { font-weight:600; }
.setting-value small { display:block; font-weight:400; color:var(--ink-2); font-size:12px; }
.segmented { display:inline-flex; gap:4px; padding:4px; border-radius:28px; background:var(--surface-2); }
.segmented label { position:relative; padding:6px 16px; border-radius:20px; font-size:13px; font-weight:600; cursor:pointer; }
.segmented input { position:absolute; opacity:0; pointer-events:none; }
.segmented label:has(input:checked) { background:var(--surface); box-shadow:0 1px 3px rgb(0 0 0 / 0.14); }
.segmented label:has(input:focus-visible) { outline:2px solid var(--accent); }
.profile-grid { display:grid; grid-template-columns:1fr 1fr; gap:0 12px; }
.profile-grid .wide { grid-column:1 / -1; }
.profile-grid .field { margin-bottom:12px; }
.profile-grid select { width:100%; padding:9px 11px; border:1px solid var(--line); border-radius:8px; background:var(--bg); color:var(--ink); font:inherit; }
.model-mult { flex:none; font-size:12px; font-weight:700; color:var(--ink-2); font-variant-numeric:tabular-nums; }
.model-pick.current { border-color:var(--accent); }
.model-picks { display:flex; flex-direction:column; gap:8px; margin-bottom:6px; }
.model-pick { display:flex; align-items:center; gap:12px; width:100%; padding:10px 14px; text-align:left; border-radius:var(--radius); }
.model-pick:hover:not(:disabled) { border-color:var(--accent); }
.model-pick:disabled, .model-pick.locked { opacity:.45; }
.model-pick:disabled { cursor:not-allowed; }
.model-pick.default { border-color:var(--accent); }
.model-pick .model-name { flex:1; min-width:0; font-weight:600; }
.model-pick .model-default { font-weight:400; font-size:12px; color:var(--ink-2); }
.model-pick .model-name small { display:block; font-weight:400; color:var(--ink-2); font-size:12px; }
.model-pick-cost[data-cost]::before { margin:0; background-color:var(--surface-2); }
.import-all { padding:4px 0 8px; font-weight:600; }
.import-list { list-style:none; padding:0; margin-top:0; margin-bottom:0; max-height:46vh; overflow-y:auto; border-top:1px solid var(--line); }
.import-list li { border-bottom:1px solid var(--line); }
.import-list .radio { padding:8px 0; }
.import-list .radio span:first-of-type { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.import-list .menu-date { flex:none; }
.price-list { list-style:none; padding:0; margin-top:0; margin-bottom:0; font-size:14px; }
.price-list li { display:flex; align-items:center; padding:5px 0; border-bottom:1px solid var(--line); }
.price-list li:last-child { border-bottom:0; }

/* Credits & billing: a page in place of the project, not a dialog over it, so the packs, the card
   and both histories have room. */
body.page-open > main, body.page-open > .statusbar, body.page-open > .capacity { display:none; }
/* FRONT DOOR: NO PROJECT, SO THE STATUS BAR HAS NOTHING TO SAY; IT COMES BACK ONLY TO CARRY AN ERROR BANNER */
body.front .statusbar-row { display:none; }
body.front .statusbar:has(> .banner[hidden]) { display:none; }
body.front > .capacity { margin-bottom:24px; }
.credits-page { max-width:880px; margin:0 auto; padding:24px 16px 48px; }
.page-head { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:18px; }
.page-head h1 { margin:0; }
.page-tabs { display:flex; gap:4px; padding:4px; border-radius:28px; background:var(--surface-2); overflow-x:auto; }
.page-tab { display:inline-flex; align-items:center; gap:7px; padding:8px 16px; border:0; border-radius:22px; background:none; color:var(--ink-2); font-size:14px; font-weight:700; white-space:nowrap; }
.page-tab .menu-icon { color:inherit; }
.page-tab[aria-selected="true"] { background:var(--surface); color:var(--ink); box-shadow:0 1px 3px rgb(0 0 0 / 0.14); }
.page-tab:hover:not([aria-selected="true"]) { color:var(--ink); }
.page-why { margin:0 0 18px; padding:12px 16px; border-left:3px solid var(--accent); border-radius:var(--radius); background:var(--surface); }
.page-grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(300px, 1fr)); gap:20px; align-items:stretch; margin-bottom:20px; }   /* cards side by side share a height */
.page-grid > .card { margin-bottom:0; }
.page-stack { display:flex; flex-direction:column; gap:20px; }
.page-stack > .card { margin-bottom:0; }
.page-grid h2 + h3, .page-grid h2 + .credits-big { margin-top:12px; }
.credits-page .ledger { max-height:none; margin-bottom:0; }
.credits-big { display:flex; align-items:center; gap:10px; margin-top:6px; font-size:34px; font-weight:700; font-variant-numeric:tabular-nums; }
.credits-big .coin { width:30px; height:30px; }
.packs { display:grid; grid-template-columns:repeat(auto-fit, minmax(120px, 1fr)); gap:10px; }
.pack { position:relative; display:flex; flex-direction:column; align-items:center; gap:2px; padding:14px 10px; border-radius:var(--radius); }
.pack:hover:not(:disabled) { border-color:var(--accent); }
.pack-credits { font-weight:700; }
.pack-price { color:var(--ink-2); font-size:13px; }
.pack-save { position:absolute; top:-9px; right:8px; padding:1px 7px; border-radius:20px; background:var(--accent); color:var(--accent-ink); font-size:11px; font-weight:600; }
.ledger { list-style:none; padding:0; margin-top:0; margin-bottom:18px; max-height:220px; overflow-y:auto; font-size:13px; }
.ledger li { display:grid; grid-template-columns:1fr auto 44px; align-items:baseline; gap:10px; padding:5px 0; border-bottom:1px solid var(--line); }
.ledger li.hint { display:block; border:0; }
.ledger b { text-align:right; font-variant-numeric:tabular-nums; }
.ledger .plus { color:var(--available); }
.ledger .minus { color:var(--ink-2); }

/* STAFF TAB: WIDER THAN THE OTHER TABS, FOR THE ACCOUNTS TABLE */
.credits-page:has(#tabStaff:not([hidden])) { max-width:1120px; }
#tabStaff .card { --card-pad: 28px; }
.staff-head { margin-bottom:12px; }
.staff-head .hint { margin:0; }
.staff-card { margin-bottom:20px; }
.staff-card .setting-row h2 { margin:0; }
.staff-kpis { display:grid; grid-template-columns:repeat(auto-fit, minmax(160px, 1fr)); gap:12px; margin-bottom:20px; }
.staff-kpi { display:flex; flex-direction:column; gap:2px; padding:16px 18px; border-radius:var(--radius); background:var(--surface); }
.staff-kpi-label { color:var(--ink-2); font-size:12px; font-weight:600; }
.staff-kpi-value { font-size:30px; font-weight:700; letter-spacing:-0.01em; font-variant-numeric:tabular-nums; }
.staff-kpi-delta, .staff-kpi-note { color:var(--ink-3); font-size:12px; font-variant-numeric:tabular-nums; }
.staff-kpi-delta { color:var(--ink-2); }

/* SIGN-UPS: ONE SERIES, SO NEUTRAL INK BARS ON A SHARED BASELINE, 2PX APART */
.staff-bars { display:grid; grid-template-columns:repeat(14, 1fr); gap:2px; height:140px; margin-top:22px; border-bottom:1px solid var(--line); }
.staff-bar { position:relative; display:flex; align-items:flex-end; height:100%; outline:none; cursor:default; }
.staff-bar span { width:100%; border-radius:4px 4px 0 0; background:var(--ink-2); }
.staff-bar:hover span, .staff-bar:focus-visible span { background:var(--ink); }
.staff-bar:hover, .staff-bar:focus-visible { background:var(--surface-2); border-radius:4px 4px 0 0; }
.staff-bar small { position:absolute; top:100%; left:50%; transform:translateX(-50%); margin-top:4px; color:var(--ink-3); font-size:10px; white-space:nowrap; }
.staff-bar em { position:absolute; left:0; right:0; top:-18px; color:var(--ink-2); font-size:11px; font-style:normal; font-weight:700; text-align:center; }
.staff-bar:first-child small { left:0; transform:none; }
.staff-bar:last-child small { left:auto; right:0; transform:none; }
.staff-readout { margin-top:24px; min-height:1.4em; color:var(--ink-2); }

/* NAMECHEAP METERS AND SERVICE VERDICTS: STATUS COLOURS, ALWAYS BESIDE A WORD */
.staff-meter { margin-top:14px; }
.staff-meter-head { display:flex; justify-content:space-between; gap:12px; font-size:14px; font-variant-numeric:tabular-nums; }
.staff-meter-bar { height:8px; margin:6px 0 4px; border-radius:4px; background:var(--surface-2); overflow:hidden; }
.staff-meter-bar span { display:block; height:100%; border-radius:4px; background:var(--available); }
.staff-meter.warn .staff-meter-bar span { background:var(--premium); }
.staff-meter.bad .staff-meter-bar span { background:var(--taken); }
.staff-meter .hint { margin:0; }
.staff-services { list-style:none; padding:0; margin:12px 0 0; font-size:14px; }
.staff-service { display:grid; grid-template-columns:10px 150px 64px 1fr; align-items:baseline; gap:10px; padding:8px 0; border-bottom:1px solid var(--line); }
.staff-dot { width:10px; height:10px; border-radius:50%; background:var(--unknown); align-self:center; }
.staff-verdict { font-size:12px; font-weight:700; color:var(--ink-2); }
.staff-detail { color:var(--ink-2); font-size:13px; overflow-wrap:anywhere; }
.staff-service.good .staff-dot { background:var(--available); }
.staff-service.good .staff-verdict { color:var(--available); }
.staff-service.bad .staff-dot { background:var(--taken); }
.staff-service.bad .staff-verdict { color:var(--taken); }
.staff-service.off .staff-dot { background:transparent; border:1.5px solid var(--ink-3); }
@media (max-width: 560px) { .staff-service { grid-template-columns:10px 1fr auto; } .staff-detail { grid-column:2 / -1; } }

/* NEWEST ACCOUNTS: THE TABLE SCROLLS INSIDE ITS CARD, NEVER THE PAGE */
.staff-table-wrap { overflow-x:auto; margin-top:12px; }
.staff-table { width:100%; border-collapse:collapse; font-size:13px; }
.staff-table th { padding:6px 10px 6px 0; border-bottom:1px solid var(--line); color:var(--ink-3); font-size:11px; font-weight:600; text-align:left; white-space:nowrap; text-transform:uppercase; letter-spacing:0.04em; }
.staff-table td { padding:8px 10px 8px 0; border-bottom:1px solid var(--line); white-space:nowrap; vertical-align:top; }
.staff-table .num { text-align:right; font-variant-numeric:tabular-nums; }
.staff-table th:nth-child(n+5) { text-align:right; }
.staff-who { white-space:normal; min-width:180px; }
.staff-who b, .staff-who a { display:block; }
.staff-who a { color:var(--ink-3); font-size:12px; text-decoration:none; }
.staff-who a:hover { text-decoration:underline; }

.share-link, .share-invite { display:flex; gap:8px; margin-top:8px; }
#shareNote:empty { display:none; }   /* the owner's radios say it already, so there is often nothing to add */
.share-link input, .share-invite input { flex:1; min-width:0; }
.share-invite input[type=email] { padding:9px 12px; border:1px solid var(--line); border-radius:8px; background:var(--surface); color:var(--ink); font:inherit; }
.share-access { display:flex; flex-direction:column; gap:6px; margin-top:16px; }
.radio { display:flex; align-items:center; gap:8px; font-size:14px; cursor:pointer; }
.radio input { accent-color:var(--accent); }
.members { list-style:none; padding:0; margin-top:0; margin-bottom:0; font-size:14px; }
.members li { display:flex; align-items:baseline; gap:10px; padding:6px 0; border-bottom:1px solid var(--line); }
.members li:first-child { border-top:1px solid var(--line); }   /* closes the list at the top too, so the first row does not read as a heading */
.members li > span:first-child { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; }
.members li .hint { margin:0; font-size:12px; }
.members li.invited > span:first-child { color:var(--ink-2); font-style:italic; }

/* VIEW ONLY: a project link opened by someone who may look but not change it. Every control that would change the project leaves the page;
   the ones that also show something (a star, a note, a ticked word) stay as a reading and stop taking clicks. The server refuses either way. */
.view-only-note { display:flex; align-items:center; gap:10px; margin:0 0 16px; padding:10px 14px; border:1px solid var(--line); border-radius:var(--radius); background:var(--surface-2); color:var(--ink-2); font-size:14px; }
	.view-only-note svg { flex:none; color:var(--ink-3); }
	.view-only-note span { flex:1; min-width:0; }
body.view-only :is(#briefEditBtn, #directionEditBtn, #staleBtn, #clearVocabBtn, #clearIdeasBtn, #vocabActionBtn, #addKeywordWrap, #listCheckBtn, #moreBtn, #addIdeaBtn, #addIdeaBarBtn, #checkBtn, #noiseBtn) { display:none; }
body.view-only :is(.tab.add, .tab.dir .side-act, .result .remove, .result .buttons :is(.tag-btn, .note-btn, .variations), .note-tag.empty, .add-ending-btn) { display:none; }
body.view-only :is(.star, .note-tag, .kw, .kw-head) { pointer-events:none; }
body.view-only .result .star:not(.on) { visibility:hidden; }   /* kept in the row so the names still line up */
#shareDlg { padding-bottom:18px; }
.capacity a { color:inherit; }

/* BILLING: the card on file, the auto top-up rule and the payments. */
.credits-billing { display:flex; align-items:baseline; justify-content:space-between; gap:12px; flex-wrap:wrap; margin-top:4px; }
.credits-billing .hint { margin:0; }
.sheet.narrow > label { display:flex; margin-left:18px; margin-right:18px; }
.billing-card { display:flex; align-items:center; gap:10px; flex-wrap:wrap; font-size:14px; }
.billing-card > span { flex:1; min-width:0; font-weight:600; font-variant-numeric:tabular-nums; }
.topup-rule { display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-top:8px; color:var(--ink-2); font-size:14px; }
.topup-rule select { padding:5px 8px; border:1px solid var(--line); border-radius:8px; background:var(--surface); color:var(--ink); font:inherit; }
.topup-rule select:disabled, .radio input:disabled { opacity:0.5; }
.inline-error { padding:8px 12px; border-radius:8px; background:var(--taken-bg); color:var(--taken); font-size:13px; }
.payments li { grid-template-columns:auto 1fr auto auto; }
.pay-what { display:flex; flex-direction:column; min-width:0; }
.pay-what small { color:var(--ink-3); font-size:11px; }
.pay-what .pay-error { color:var(--taken); }
.pay-status { color:var(--ink-3); font-size:12px; white-space:nowrap; }
.pay-status a { color:var(--accent-text); }
.pay-failed .pay-status { color:var(--taken); }
.pay-refunded b, .pay-failed b { color:var(--ink-3); text-decoration:line-through; }

/* --- HOME AURA --- */
/* A slow glow across the top of the front door, like a hero banner, in the brand yellow, white and
   a little sky blue, with halftone dot discs drifting through it. Its layers travel with most of the
   scroll, so it stays on screen for a while and fades out over the box's tall masked foot. Only transforms animate, so it stays on the compositor; it fades out (and
   stops painting) once the first brief or name is sent. */
:root { --aura-top:#fffdf1; --aura-sun:rgb(250 208 0 / .5); --aura-sea:rgb(110 185 255 / .2); --aura-light:rgb(255 255 255 / .95); --aura-dot:rgb(28 43 85 / .13); --aura-dot-sun:rgb(176 140 0 / .2); --aura-grain:.16; }
:root.dark { --aura-top:#191c27; --aura-sun:rgb(250 208 0 / .2); --aura-sea:rgb(110 185 255 / .2); --aura-light:rgb(255 255 255 / .05); --aura-dot:rgb(255 255 255 / .09); --aura-dot-sun:rgb(250 208 0 / .16); --aura-grain:.22; }
.aura { position:absolute; top:0; left:0; right:0; z-index:-1; height:0; overflow:hidden; pointer-events:none; opacity:0; visibility:hidden; transition:opacity 1.8s ease, visibility 0s linear 1.8s, height 0s linear 1.8s; background:radial-gradient(120% 90% at 50% 0%, var(--aura-top), var(--bg) 75%); -webkit-mask:linear-gradient(#000 28%, transparent 85%); mask:linear-gradient(#000 28%, transparent 85%); }
body.front:not(.aura-off) .aura { height:min(230vh, 2200px); opacity:1; visibility:visible; transition:opacity 1.8s ease; }   /* off, the height drops to 0 once faded: a hidden box this tall still stretched project pages into blank space */
/* PROJECT LOADER: the glow over the page, with a ring in the middle, while a project link fills in
   behind it. It covers the status bar (20) but sits under the header (25) and starts right of the
   projects, so both stay usable. app.js takes .loading off the body once the project is on screen. */
.loader { position:fixed; top:0; right:0; bottom:0; left:var(--side); z-index:22; display:grid; place-items:center; background:var(--bg); transition:opacity .25s ease, left .18s ease; }   /* coming up, quickly: a project link is waiting on it */
body:not(.loading) .loader { opacity:0; visibility:hidden; pointer-events:none; transition:opacity .4s ease, visibility 0s linear .4s, left .18s ease; }   /* going, slower, and only hidden once it has faded */
	.loader .aura { inset:0; height:auto; opacity:1; visibility:visible; }
	/* The front door's drift at a working pace: a load lasts a second or two, and at 46-140s a cycle nothing would visibly move. The negative delays
	   start each layer mid-swing, already moving, rather than easing in from still. Reduced motion still stops them (the !important rule below). */
	.loader .aura-sun { animation-duration:5s; animation-delay:-1.5s; } .loader .aura-sea { animation-duration:6s; animation-delay:-2s; } .loader .aura-light { animation-duration:5.5s; animation-delay:-1s; }
	.loader .aura-swirl { animation-duration:9s; }
	.loader .aura .d1 { animation-duration:8s; animation-delay:-3s; } .loader .aura .d2 { animation-duration:7s; animation-delay:-2s; } .loader .aura .d3 { animation-duration:6s; animation-delay:-2.5s; } .loader .aura .d4 { animation-duration:7.5s; animation-delay:-1s; } .loader .aura .d5 { animation-duration:6.5s; animation-delay:-3s; }
	.loader-spin { position:relative; width:34px; height:34px; border:3px solid color-mix(in srgb, var(--ink) 14%, transparent); border-top-color:var(--accent); border-radius:50%; animation:spin .8s linear infinite; }
.aura > span { position:absolute; border-radius:50%; will-change:transform; }
.aura-sun { width:62vmax; height:62vmax; left:-16vmax; top:-30vmax; background:radial-gradient(circle, var(--aura-sun), transparent 66%); animation:aura-sun 46s ease-in-out infinite alternate; }
.aura-sea { width:56vmax; height:56vmax; right:-20vmax; top:-18vmax; background:radial-gradient(circle, var(--aura-sea), transparent 66%); animation:aura-sea 60s ease-in-out infinite alternate; }
.aura-light { width:50vmax; height:50vmax; left:24vw; top:-6vmax; background:radial-gradient(circle, var(--aura-light), transparent 68%); animation:aura-light 52s ease-in-out infinite alternate; }
/* The Gemini-ish swirl: a conic wash, softened at the middle and the edge, turning very slowly. */
.aura-swirl { width:80vmax; height:80vmax; left:calc(50% - 40vmax); top:-48vmax; opacity:.55; background:conic-gradient(from 0deg, var(--aura-sun), transparent 22%, var(--aura-sea) 40%, transparent 58%, var(--aura-light) 72%, transparent 86%, var(--aura-sun)); -webkit-mask:radial-gradient(closest-side, transparent 18%, #000 45%, transparent 100%); mask:radial-gradient(closest-side, transparent 18%, #000 45%, transparent 100%); animation:aura-spin 140s linear infinite; }
/* Halftone dot discs: a fine grid of dots, faded to nothing at the rim. Each one varies its size, pitch and drift. */
.aura .dots { --d:30vmax; --pitch:13px; --dot:1.3px; width:var(--d); height:var(--d); background:radial-gradient(var(--c, var(--aura-dot)) var(--dot), transparent calc(var(--dot) + .5px)) 0 0/var(--pitch) var(--pitch); -webkit-mask:radial-gradient(closest-side, #000 25%, transparent); mask:radial-gradient(closest-side, #000 25%, transparent); animation:var(--a) ease-in-out infinite alternate; }
.aura .d1 { --d:34vmax; left:-6vmax; top:4vh; --a:aura-d1 90s; }
.aura .d2 { --d:26vmax; right:4vw; top:-6vmax; --pitch:11px; --dot:1.1px; --c:var(--aura-dot-sun); --a:aura-d2 76s; }
.aura .d3 { --d:18vmax; left:38vw; top:30vh; --pitch:9px; --dot:1px; --a:aura-d3 64s; }
.aura .d4 { --d:22vmax; right:-4vmax; top:36vh; --pitch:15px; --dot:1.6px; --a:aura-d4 84s; }
.aura .d5 { --d:14vmax; left:18vw; top:-3vmax; --pitch:10px; --c:var(--aura-dot-sun); --a:aura-d5 70s; }
/* Parallax: app.js eases the scroll position (--sy, in px) and the pointer (--mx and --my, -1 to 1 across the
   window) onto .aura. Each layer travels with the scroll by its --depth, kept close together because a big spread
   reads as sliding and is queasy, and follows the pointer by a few --px, negative to move against it. The separate translate and rotate properties add to the running animations rather than replacing them. */
.aura > span { translate:calc(var(--mx, 0) * var(--px, 30) * 1px) calc(var(--sy, 0) * var(--depth, .3) * 1px + var(--my, 0) * var(--px, 30) * 1px); }
.aura-sun { --depth:.82; --px:18; } .aura-sea { --depth:.78; --px:-20; } .aura-light { --depth:.85; --px:40; }
.aura-swirl { --depth:.8; --px:-12; rotate:calc(var(--sy, 0) * .03deg + var(--mx, 0) * 3deg); }
.aura .d1 { --depth:.74; --px:-8; } .aura .d2 { --depth:.8; --px:12; } .aura .d3 { --depth:.7; --px:-14; } .aura .d4 { --depth:.76; --px:6; } .aura .d5 { --depth:.84; --px:14; }
/* Grain over the lot, so the gradients read as a surface rather than a screen. */
.aura::after { content:""; position:absolute; inset:0; opacity:var(--aura-grain); mix-blend-mode:overlay; background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
@keyframes aura-sun { to { transform:translate(16vw, 8vh) scale(1.18); } }
@keyframes aura-sea { to { transform:translate(-14vw, 12vh) scale(.88); } }
@keyframes aura-light { to { transform:translate(-12vw, 10vh) scale(1.12); } }
@keyframes aura-spin { to { transform:rotate(360deg); } }
@keyframes aura-d1 { to { transform:translate(8vw, 6vh) rotate(-30deg); } }
@keyframes aura-d2 { to { transform:translate(-10vw, 10vh) rotate(25deg) scale(1.1); } }
@keyframes aura-d3 { to { transform:translate(12vw, -10vh) rotate(40deg) scale(.9); } }
@keyframes aura-d4 { to { transform:translate(-8vw, -14vh) rotate(-20deg); } }
@keyframes aura-d5 { to { transform:translate(6vw, 12vh) rotate(35deg) scale(1.2); } }
@media (prefers-reduced-motion: reduce) {
	.aura > span { animation:none !important; }   /* the global rule would shrink these to a flicker, not stop them */
}
/* The title bar as frosted glass and the cards as clear glass over the glow, on the home screen only. */
.topbar, .card { transition:background-color .6s ease, border-color .6s ease, box-shadow .6s ease; }
body.front .topbar { background:color-mix(in srgb, var(--surface) 45%, transparent); border-bottom-color:color-mix(in srgb, var(--line) 55%, transparent); box-shadow:inset 0 -1px 0 rgb(255 255 255 / .35); -webkit-backdrop-filter:blur(22px) saturate(1.6); backdrop-filter:blur(22px) saturate(1.6); }
body.front:not(.aura-off) .card { background:color-mix(in srgb, var(--surface) 62%, transparent); box-shadow:inset 0 0 0 1px rgb(255 255 255 / .55), 0 12px 40px rgb(28 43 85 / .07); }
/* The fills inside go clear with them; the colours are spelt out because a variable cannot be mixed from itself. */
body.front:not(.aura-off) :is(.card, .topbar) { --surface-2:color-mix(in srgb, #f0efec 55%, transparent); }
:root.dark body.front:not(.aura-off) :is(.card, .topbar) { --surface-2:color-mix(in srgb, #2b2b24 60%, transparent); }
:root.dark body.front .topbar { box-shadow:inset 0 -1px 0 rgb(255 255 255 / .05); }
:root.dark body.front:not(.aura-off) .card { background:color-mix(in srgb, var(--surface) 70%, transparent); box-shadow:inset 0 0 0 1px rgb(255 255 255 / .06), 0 12px 40px rgb(0 0 0 / .25); }

/* COOKIE CONSENT: A SMALL CARD BOTTOM LEFT, CLEAR OF THE SIDEBAR AND, ON A PROJECT, THE STATUS BAR */
.consent { position:fixed; left:calc(var(--side) + 16px); bottom:calc(var(--bar) + 12px); z-index:25; display:flex; align-items:center; gap:14px; max-width:440px; padding:12px 14px 12px 16px; border:1px solid var(--line); border-radius:var(--radius); background:var(--surface); box-shadow:0 6px 24px rgb(0 0 0 / 0.12); font-size:13px; color:var(--ink-2); }
	.consent p { margin:0; }
	.consent a { color:inherit; }
body.front .consent { bottom:16px; }   /* no status bar on the front door */
.consent-actions { display:flex; gap:8px; flex:none; }
.capacity .link-inline { padding:0; border:0; background:none; color:inherit; font:inherit; text-decoration:underline; cursor:pointer; }
@media (max-width: 560px) {
	.consent { left:16px; right:16px; flex-wrap:wrap; max-width:none; }
	.consent-actions { margin-left:auto; }
}

/* --- AI WAIT --- */
/* While an AI call runs: a glass pill with a spinning ring, pulsing core and shimmering label floats at the top of the window, and a scan line sweeps along its top edge. */
.ai-wait { position:fixed; top:12px; left:calc(var(--side) + (100% - var(--side)) / 2); z-index:26; display:flex; align-items:center; gap:10px; padding:7px 16px 7px 8px; border-radius:999px; background:color-mix(in srgb, var(--surface) 72%, transparent); box-shadow:inset 0 0 0 1px rgb(255 255 255 / .55), 0 10px 30px rgb(110 185 255 / .28), 0 2px 8px rgb(0 0 0 / .08); -webkit-backdrop-filter:blur(16px) saturate(1.6); backdrop-filter:blur(16px) saturate(1.6); font-size:13px; font-weight:600; letter-spacing:.02em; white-space:nowrap; pointer-events:none; opacity:0; transform:translate(-50%, -14px) scale(.96); transition:opacity .35s ease, transform .45s cubic-bezier(.2,.8,.2,1); }
body.ai-busy .ai-wait { opacity:1; transform:translate(-50%, 0) scale(1); }
:root.dark .ai-wait { box-shadow:inset 0 0 0 1px rgb(255 255 255 / .08), 0 10px 30px rgb(110 185 255 / .18), 0 2px 8px rgb(0 0 0 / .3); }
.ai-orb { position:relative; flex:none; width:24px; height:24px; }
.ai-orb::before { content:""; position:absolute; inset:0; border-radius:50%; background:conic-gradient(transparent 0 20%, #6eb9ff 55%, var(--accent) 88%, transparent); -webkit-mask:radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px)); mask:radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px)); animation:ai-spin .9s linear infinite; }
.ai-orb::after { content:""; position:absolute; inset:7px; border-radius:50%; background:radial-gradient(circle at 35% 35%, #fff, var(--accent) 60%); box-shadow:0 0 10px 2px rgb(250 208 0 / .55); animation:ai-pulse 1.6s ease-in-out infinite; }
.ai-label { background:linear-gradient(90deg, var(--ink) 0 35%, #6eb9ff 50%, var(--ink) 65% 100%) 0 0/250% 100%; -webkit-background-clip:text; background-clip:text; color:transparent; animation:ai-shimmer 2.4s linear infinite; }
.ai-label::after { content:"…"; }
.ai-scan { position:fixed; top:0; left:var(--side); right:0; z-index:26; height:2px; overflow:hidden; pointer-events:none; opacity:0; transition:opacity .35s ease; }
body.ai-busy .ai-scan { opacity:1; }
.ai-scan::before { content:""; position:absolute; top:0; bottom:0; left:0; width:40%; background:linear-gradient(90deg, transparent, #6eb9ff, var(--accent), transparent); animation:ai-scan 1.8s cubic-bezier(.45,0,.25,1) infinite; }
@media (max-width: 720px) {
	.ai-wait { top:70px; }   /* below the topbar, whose buttons fill a phone's width */
}
@keyframes ai-spin { to { transform:rotate(360deg); } }
@keyframes ai-pulse { 50% { transform:scale(.7); opacity:.7; } }
@keyframes ai-shimmer { from { background-position:100% 0; } to { background-position:0 0; } }
@keyframes ai-scan { from { transform:translateX(-100%); } to { transform:translateX(250%); } }
@media (prefers-reduced-motion: reduce) {
	.ai-orb::before, .ai-orb::after, .ai-label, .ai-scan::before { animation:none !important; }
}

/* --- NEW ROW FLASH --- */
/* A name just added and scrolled to glows yellow and fades back, so the eye finds where the sort put it. */
.result.landed { animation:row-landed 2.4s ease-out; }
@keyframes row-landed { from { background-color:color-mix(in srgb, var(--accent) 38%, transparent); box-shadow:0 0 0 2px var(--accent); } }
