/**
 * Copyright (c) 2026 AInvirion LLC. All Rights Reserved.
 *
 * PROPRIETARY AND CONFIDENTIAL
 *
 * This source code is the proprietary and confidential property of AInvirion LLC.
 * Unauthorized copying, modification, distribution, or use of this file,
 * via any medium, is strictly prohibited without written permission from AInvirion LLC.
 */

/* The console's design system.
 *
 * This is the surface the *owner* sees — sign-in, their sites, the editor, the
 * import flow, the admin screens. It is deliberately separate from
 * `zzsites/design/`, which styles the sites we publish: those are a customer's
 * brand and are governed by the section property allowlist (spec 01 §1.5).
 * Nothing here is subject to that allowlist, and nothing here ever reaches a
 * published page.
 *
 * It used to be an inline `<style>` block in `base.html`, which is why every
 * screen had square corners, uppercase buttons and no accent colour: there was
 * nowhere to put a component, so every template invented its own spacing. The
 * rule now is that a screen composes the classes below and adds nothing of its
 * own. If a screen needs something this file does not have, it goes in here.
 *
 * Layers, in order: tokens, reset, shell, typography, controls, components.
 */

/* ==================================================================== */
/* Tokens                                                               */
/* ==================================================================== */

:root {
  /* Ink is near-black with a blue cast rather than pure #000 — black on white
     is harsher than any screen needs, and the cast ties the greys to the
     accent so the palette reads as one decision. */
  --ink:        #14112b;
  --ink-2:      #3f3b5c;
  --sub:        #6e6a89;
  --faint:      #9b98ad;

  --bg:         #ffffff;
  --panel:      #f7f7fb;
  --panel-2:    #f0eff7;
  --line:       #e6e4f0;
  --line-2:     #f0eff6;

  --accent:     #5b4bf5;
  --accent-ink: #ffffff;
  --accent-dark:#4638d8;
  --accent-soft:#eeecff;
  --accent-line:#cfcaff;

  --ok:         #0d7346;
  --ok-soft:    #e8f6ef;
  --ok-line:    #bde3d0;
  --warn:       #8a5300;
  --warn-soft:  #fdf5e6;
  --warn-line:  #eeddb8;
  --danger:     #b3261e;
  --danger-soft:#fdecea;
  --danger-line:#f2c6c2;

  /* Type. One family, four sizes above the base and two below it. */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --fs-xs:   0.75rem;
  --fs-sm:   0.8125rem;
  --fs-base: 0.9375rem;
  --fs-md:   1.0625rem;
  --fs-lg:   1.375rem;
  --fs-xl:   1.875rem;
  --fs-2xl:  2.5rem;

  /* Space. A 4px scale — every gap in the console is one of these. */
  --sp-1: 0.25rem;  --sp-2: 0.5rem;   --sp-3: 0.75rem;
  --sp-4: 1rem;     --sp-5: 1.5rem;   --sp-6: 2rem;
  --sp-7: 3rem;     --sp-8: 4rem;

  --r-sm:   6px;
  --r:      10px;
  --r-lg:   14px;
  --r-pill: 999px;

  --shadow-sm: 0 1px 2px rgb(20 17 43 / 0.06);
  --shadow:    0 1px 3px rgb(20 17 43 / 0.06), 0 8px 24px -10px rgb(20 17 43 / 0.14);
  --shadow-lg: 0 2px 6px rgb(20 17 43 / 0.06), 0 20px 48px -16px rgb(20 17 43 / 0.20);

  --header-h: 3.5rem;

  color-scheme: light;
}

/* ==================================================================== */
/* Reset                                                                */
/* ==================================================================== */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-base);
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img { max-width: 100%; height: auto; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* ==================================================================== */
/* Shell — the header and the page column                               */
/* ==================================================================== */

.site-header {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  height: var(--header-h);
  padding: 0 var(--sp-5);
  background: rgb(255 255 255 / 0.85);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 20;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-base);
  font-weight: 650;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
  flex: none;
}
.brand .bolt { display: block; flex: none; color: var(--accent); }

.site-nav-group { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; }
.site-nav { display: flex; align-items: center; gap: var(--sp-1); }
.site-nav a {
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--sub);
  text-decoration: none;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  white-space: nowrap;
}
.site-nav a:hover { color: var(--ink); background: var(--panel); }
.site-nav a[aria-current="page"] { color: var(--ink); background: var(--panel-2); }

/* The admin group sits behind a hairline so it reads as a different tier of
   navigation rather than four more of the owner's own screens. */
.site-nav.admin { padding-left: var(--sp-3); border-left: 1px solid var(--line); }

.who {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--sub);
}
.who .avatar {
  width: 1.75rem; height: 1.75rem;
  border-radius: var(--r-pill);
  background: var(--accent-soft);
  color: var(--accent-dark);
  border: 1px solid var(--accent-line);
  font-size: var(--fs-xs);
  font-weight: 650;
  display: grid; place-items: center;
  text-transform: uppercase;
  overflow: hidden;
  flex: none;
}
.who img.avatar { object-fit: cover; border-color: var(--line); }
.who .name { color: var(--ink); font-weight: 500; }
.who button {
  font: inherit;
  font-size: var(--fs-sm);
  color: var(--sub);
  background: none;
  border: 0;
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-sm);
  cursor: pointer;
}
.who button:hover { color: var(--ink); background: var(--panel); }

/* A phone cannot fit the brand, both navs and the account on one row, and a
   header that does not fit is a page that scrolls sideways — every screen at
   once, because the header is on every screen. Below the breakpoint the pair
   of navs drops to a second row and the account keeps its place beside the
   brand, so nothing is hidden and nothing overflows. */
@media (max-width: 47.99em) {
  .site-header {
    flex-wrap: wrap;
    height: auto;
    min-height: var(--header-h);
    padding-block: var(--sp-2);
    gap: var(--sp-3);
    row-gap: var(--sp-1);
  }
  .brand { order: 1; }
  .who   { order: 2; }
  .site-nav-group {
    order: 3;
    flex-basis: 100%;
    /* Enough room for four items on the narrowest phone; scrolling the strip
       beats dropping a screen out of reach. */
    overflow-x: auto;
    scrollbar-width: none;
  }
  .site-nav-group::-webkit-scrollbar { display: none; }
  .site-nav a { padding-inline: var(--sp-2); }
  /* The avatar and the sign-out still identify the account; the given name is
     the part that can go when the row is short of room. */
  .who .name { display: none; }
}

main {
  max-width: 52rem;
  margin: 0 auto;
  padding: var(--sp-7) var(--sp-5) var(--sp-8);
}
/* The editor is a two-pane workbench and wants the whole window. */
main:has(.workbench) { max-width: 92rem; padding: var(--sp-5) var(--sp-5) var(--sp-7); }
/* So does anything that says so outright. */
main:has(> .wide) { max-width: 76rem; }
/* A single centred card — sign-in, invite, waitlist. */
main:has(> .auth-card) { max-width: 27rem; padding-top: var(--sp-8); }

/* ==================================================================== */
/* Typography                                                           */
/* ==================================================================== */

h1 {
  font-size: var(--fs-xl);
  font-weight: 650;
  letter-spacing: -0.025em;
  line-height: 1.2;
  margin: 0 0 var(--sp-3);
}
h2 {
  font-size: var(--fs-md);
  font-weight: 650;
  letter-spacing: -0.015em;
  margin: var(--sp-7) 0 var(--sp-3);
}
h3 {
  font-size: var(--fs-base);
  font-weight: 650;
  letter-spacing: -0.01em;
  margin: var(--sp-5) 0 var(--sp-2);
}
/* The first heading on a screen has the page's own top padding above it. */
h1:first-child, h2:first-child, h3:first-child { margin-top: 0; }

p { margin: 0 0 var(--sp-4); }
p:last-child { margin-bottom: 0; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

.muted { color: var(--sub); }
.small { font-size: var(--fs-sm); }
.lede  { font-size: var(--fs-md); color: var(--ink-2); line-height: 1.55; }

code, kbd, samp, pre { font-family: var(--mono); font-size: 0.92em; }
code {
  background: var(--panel);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  padding: 0.1em 0.35em;
}
pre {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: var(--sp-3);
  overflow-x: auto;
}
pre code { background: none; border: 0; padding: 0; }

/* The invite code, wherever it is shown to be read aloud or typed. */
.code {
  font-family: var(--mono);
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: 0.08em;
  background: none; border: 0; padding: 0;
}

/* A page's title block: heading, one line under it, and nothing else. */
.page-head { margin: 0 0 var(--sp-6); }
.page-head h1 { margin-bottom: var(--sp-2); }
.page-head p  { margin: 0; color: var(--sub); }

/* ==================================================================== */
/* Controls                                                             */
/* ==================================================================== */

button, .btn { cursor: pointer; }
button:disabled, .btn:disabled { cursor: not-allowed; opacity: 0.5; }

/* One button shape — a pill — in three weights. Sentence case, never
   uppercase-with-tracking: that treatment is what dated every screen. */
.btn, button.primary, button.quiet, button.danger {
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 550;
  line-height: 1.2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.btn:hover, button.primary:hover, button.quiet:hover, button.danger:hover {
  text-decoration: none;
}

button.primary, .btn.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}
button.primary:hover, .btn.primary:hover {
  background: var(--accent-dark);
  border-color: var(--accent-dark);
}

button.quiet, .btn.quiet {
  background: var(--bg);
  border-color: var(--line);
  color: var(--ink);
  box-shadow: var(--shadow-sm);
}
button.quiet:hover, .btn.quiet:hover { border-color: var(--faint); background: var(--panel); }

button.danger, .btn.danger {
  background: var(--bg);
  border-color: var(--danger-line);
  color: var(--danger);
}
button.danger:hover, .btn.danger:hover { background: var(--danger-soft); border-color: var(--danger); }

/* A button that is really a link — "Delete this page", "Undo". The element
   selector is carried through every rule here because the pill variants above
   are written as `button.danger`, which outranks a bare `.btn-link`. */
button.btn-link, .btn-link {
  font: inherit;
  font-size: var(--fs-sm);
  background: none;
  border: 0;
  padding: 0;
  color: var(--sub);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
button.btn-link:hover, .btn-link:hover { color: var(--ink); }
button.btn-link.danger, .btn-link.danger { color: var(--danger); }

/* A small square control that carries one glyph — the reorder arrows. */
.icon-btn {
  font: inherit;
  font-size: var(--fs-sm);
  width: 1.875rem; height: 1.875rem;
  display: inline-grid; place-items: center;
  padding: 0;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--sub);
  cursor: pointer;
  transition: color .12s ease, border-color .12s ease, background-color .12s ease;
}
.icon-btn:hover { color: var(--ink); border-color: var(--faint); background: var(--panel); }

/* --- fields --------------------------------------------------------- */

form.stack { display: grid; gap: var(--sp-4); }
form.stack > button, form.stack > .actions { justify-self: start; }

label {
  display: grid;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: 550;
  color: var(--ink);
}
label .muted, label .hint { font-weight: 400; }

input, textarea, select {
  font: inherit;
  font-size: var(--fs-base);
  font-weight: 400;
  color: var(--ink);
  padding: var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--bg);
  width: 100%;
  transition: border-color .12s ease, box-shadow .12s ease;
}
input::placeholder, textarea::placeholder { color: var(--faint); }
input:hover, textarea:hover, select:hover { border-color: var(--faint); }
input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
textarea { resize: vertical; min-height: 6rem; line-height: 1.55; }
textarea.richtext, textarea.textarea { min-height: 7rem; }

select {
  appearance: none;
  padding-right: var(--sp-7);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%236e6a89' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--sp-3) center;
}

input[type="checkbox"] {
  width: 1.05rem; height: 1.05rem;
  accent-color: var(--accent);
  padding: 0;
  justify-self: start;
}

/* The browser's own file control is the single most dated thing on any
   screen. Hide it and drive a styled label instead; the input keeps working
   exactly as it did, so nothing about validation or submission changes. */
.file {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-4);
  border: 1px dashed var(--line);
  border-radius: var(--r);
  background: var(--panel);
  font-weight: 400;
  color: var(--sub);
  cursor: pointer;
  transition: border-color .12s ease, background-color .12s ease;
}
.file:hover { border-color: var(--accent-line); background: var(--accent-soft); }
/* The native control is clipped to 1px, so its own focus ring lands on
   something nobody can see. The ring has to move to the thing that is
   visible, or tabbing to the picker looks like a control that did not
   respond. Same treatment a focused text field gets, for the same reason. */
.file:focus-within {
  border-color: var(--accent);
  border-style: solid;
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.file:focus-within .file-cue { border-color: var(--accent); }
.file input[type="file"] {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
.file .file-cue {
  font-size: var(--fs-sm);
  font-weight: 550;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  padding: var(--sp-2) var(--sp-4);
  flex: none;
}
.file .file-name { font-size: var(--fs-sm); min-width: 0; overflow-wrap: anywhere; }

label.has-error input, label.has-error textarea, label.has-error select { border-color: var(--danger); }
label.has-error input:focus, label.has-error textarea:focus, label.has-error select:focus {
  box-shadow: 0 0 0 3px var(--danger-soft);
}
.error { color: var(--danger); font-size: var(--fs-sm); font-weight: 400; }

fieldset {
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: var(--sp-4);
  margin: 0;
  display: grid;
  gap: var(--sp-4);
  background: var(--bg);
}
legend {
  font-size: var(--fs-xs);
  font-weight: 650;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--sub);
  padding: 0 var(--sp-2);
}

/* Fields side by side where they are short and read as a set — an address,
   a week of opening hours. One column on a phone, always. */
.field-grid {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}
.field-grid > label.wide { grid-column: 1 / -1; }

/* Cards stacked down a form need air between them, and the buttons need more
   than that so they do not read as part of the last card. */
form > .card + .card { margin-top: var(--sp-4); }
form > .card + .actions { margin-top: var(--sp-5); }
.card > h2 { margin: 0 0 var(--sp-4); font-size: var(--fs-base); }
.card > h2 + p { margin-top: calc(var(--sp-4) * -1 + var(--sp-1)); }

/* The days a business is open — a row of toggles, not seven more rows of
   form. `label` is a grid everywhere else, so these opt out of it. */
fieldset.days {
  border: 0;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  align-items: center;
}
fieldset.days legend {
  padding: 0;
  margin-bottom: var(--sp-2);
  float: left;
  width: 100%;
}
label.day {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: 500;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--bg);
  cursor: pointer;
  user-select: none;
  transition: border-color .12s ease, background-color .12s ease;
}
label.day:hover { border-color: var(--faint); }
label.day:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-dark);
}
label.day:has(input:focus-visible) { box-shadow: 0 0 0 3px var(--accent-soft); }
label.day:has(input:disabled) { opacity: 0.55; cursor: not-allowed; }
label.day input { margin: 0; }

/* A field the screen has taken out of play still has to read as one. */
input:disabled { background: var(--panel); color: var(--sub); cursor: not-allowed; }

/* ==================================================================== */
/* Components                                                           */
/* ==================================================================== */

/* --- messages ------------------------------------------------------- */

.notice, .warn, .warning, .flash {
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r);
  border: 1px solid var(--line);
  background: var(--panel);
  font-size: var(--fs-sm);
  margin: 0 0 var(--sp-5);
}
.warn, .warning { background: var(--warn-soft); border-color: var(--warn-line); color: var(--warn); }
.flash { background: var(--ok-soft); border-color: var(--ok-line); color: var(--ok); }
p.error[role="alert"] {
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r);
  background: var(--danger-soft);
  border: 1px solid var(--danger-line);
  margin: 0 0 var(--sp-5);
}

/* --- cards ---------------------------------------------------------- */

.card {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
  box-shadow: var(--shadow-sm);
}

.auth-card {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--sp-6);
  box-shadow: var(--shadow);
}
.auth-card h1 { font-size: var(--fs-lg); }
.auth-card + .auth-aside {
  margin-top: var(--sp-5);
  text-align: center;
  font-size: var(--fs-sm);
  color: var(--sub);
}

/* --- badges --------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--fs-xs);
  font-weight: 600;
  padding: 0.15rem var(--sp-2);
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--sub);
  white-space: nowrap;
}
.badge.live  { background: var(--ok-soft);     border-color: var(--ok-line);     color: var(--ok); }
.badge.draft { background: var(--warn-soft);   border-color: var(--warn-line);   color: var(--warn); }
.badge.todo  { background: var(--warn-soft);   border-color: var(--warn-line);   color: var(--warn); }
.badge.accent{ background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-dark); }

/* The dot before "Live". A ring rather than a tick — a tick claims the site
   is correct, which we do not know; a lit dot only claims it is up. */
.badge.live::before {
  content: "";
  width: 0.4rem; height: 0.4rem;
  border-radius: var(--r-pill);
  background: currentColor;
}

/* --- tables --------------------------------------------------------- */

.table-wrap {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--bg);
}
.table-wrap + .table-wrap { margin-top: var(--sp-4); }
/* Wide tables scroll inside their own frame; the page never does. */
.table-wrap.scroll { overflow-x: auto; }

table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
th {
  text-align: left;
  font-size: var(--fs-xs);
  font-weight: 650;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--sub);
  padding: var(--sp-3) var(--sp-4);
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
td {
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line-2);
  vertical-align: middle;
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--panel); }
td.num { text-align: right; font-variant-numeric: tabular-nums; }

/* A cell that cannot break makes the whole table wider than its frame, and
   the frame is what scrolls — so every column past the edge disappears with
   no sign that it is there. A publish error carries an object key sixty
   characters long with no space in it, which on a 1440px screen pushed the
   rollback button itself out of sight. Breaking mid-token is the lesser
   evil: an ugly wrap beats a hidden control. */
td.breakable, td .breakable, td code { overflow-wrap: anywhere; }

/* Six columns do not fit a phone however they wrap, and a column scrolled
   past the frame's edge is a column nobody knows is there. A screen this
   narrow drops the two that are only ever context; the one carrying the
   button never goes. */
@media (max-width: 47.99em) {
  th.on-wide, td.on-wide { display: none; }
}

/* --- the empty state ------------------------------------------------- */

.empty {
  text-align: center;
  padding: var(--sp-7) var(--sp-5);
  border: 1px dashed var(--line);
  border-radius: var(--r-lg);
  background: var(--panel);
  color: var(--sub);
}
.empty h2 { margin: 0 0 var(--sp-2); color: var(--ink); font-size: var(--fs-md); }
.empty p { margin: 0 auto var(--sp-5); max-width: 30rem; }
.empty p:last-child { margin-bottom: 0; }

/* --- provider buttons ------------------------------------------------ */

.choices { display: grid; gap: var(--sp-3); margin: var(--sp-5) 0 0; }
.provider {
  font: inherit;
  font-size: var(--fs-base);
  font-weight: 550;
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  text-decoration: none;
  padding: var(--sp-3) var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--bg);
  box-shadow: var(--shadow-sm);
  width: 100%;
  cursor: pointer;
  transition: border-color .12s ease, background-color .12s ease;
}
.provider:hover { border-color: var(--faint); background: var(--panel); text-decoration: none; }
.provider .mark { flex: none; display: block; }

/* --- a row of controls ----------------------------------------------- */

.row { display: flex; gap: var(--sp-2); align-items: center; }
.row.wrap { flex-wrap: wrap; }
.grow { flex: 1; min-width: 0; }
a.grow { text-decoration: none; color: inherit; }
.actions { display: flex; gap: var(--sp-3); align-items: center; flex-wrap: wrap; }
.spacer { flex: 1; }

/* A `<details>` used as a disclosure for a form — "+ page", "Add a section".
   The default marker triangle is the tell of an unstyled page. */
details.disclosure > summary {
  list-style: none;
  cursor: pointer;
  font-size: var(--fs-sm);
  font-weight: 550;
  color: var(--accent);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
}
details.disclosure > summary::-webkit-details-marker { display: none; }
details.disclosure > summary::before {
  content: "+";
  font-size: var(--fs-md);
  line-height: 1;
  font-weight: 400;
}
details.disclosure[open] > summary::before { content: "\2212"; }
details.disclosure > summary:hover { background: var(--accent-soft); }
details.disclosure[open] > summary { margin-bottom: var(--sp-3); }
details.disclosure > form,
details.disclosure > .card { margin-bottom: var(--sp-3); }

/* ==================================================================== */
/* The editor                                                           */
/* ==================================================================== */

/* --- the site bar ---------------------------------------------------- */

.site-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  padding-bottom: var(--sp-4);
  margin-bottom: var(--sp-4);
  border-bottom: 1px solid var(--line);
}
.site-bar .site-name {
  font-size: var(--fs-lg);
  font-weight: 650;
  letter-spacing: -0.02em;
}
.site-bar .host {
  font-size: var(--fs-sm);
  color: var(--sub);
  font-family: var(--mono);
}
.site-bar a.host:hover { color: var(--accent); }

/* --- the page tabs --------------------------------------------------- */

nav.pages {
  display: flex;
  gap: var(--sp-1);
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: var(--sp-5);
}
nav.pages a {
  color: var(--sub);
  text-decoration: none;
  font-size: var(--fs-sm);
  font-weight: 550;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
}
nav.pages a:hover { color: var(--ink); background: var(--panel); }
nav.pages a.current { color: var(--ink); background: var(--panel-2); }
nav.pages details.disclosure { position: relative; }
/* The add-a-page form floats over the workbench instead of pushing the tabs
   apart, which used to shove the whole preview down the screen. */
nav.pages details.disclosure[open] > summary { margin-bottom: 0; }
nav.pages details.disclosure > .card {
  position: absolute;
  z-index: 15;
  top: calc(100% + var(--sp-2));
  left: 0;
  width: 20rem;
  box-shadow: var(--shadow-lg);
  margin: 0;
}

/* --- the two panes --------------------------------------------------- */

.workbench { display: grid; gap: var(--sp-5); align-items: start; }
@media (min-width: 64em) {
  .workbench { grid-template-columns: minmax(24rem, 34rem) 1fr; }
  .preview { position: sticky; top: calc(var(--header-h) + var(--sp-4)); }
}

.editor-pane { display: grid; gap: var(--sp-3); }

/* --- a section row --------------------------------------------------- */

.section {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--bg);
  box-shadow: var(--shadow-sm);
  transition: border-color .12s ease, box-shadow .12s ease;
}
.section:not(.open):hover { border-color: var(--faint); box-shadow: var(--shadow); }
.section.hidden { background: var(--panel); }
.section.hidden .section-label { color: var(--sub); }
.section.invalid { border-left: 3px solid var(--warn-line); }
.section.open { border-color: var(--accent-line); box-shadow: var(--shadow); }

.section > .row { padding: var(--sp-3) var(--sp-3) var(--sp-3) var(--sp-4); }
.section .section-label { font-weight: 600; font-size: var(--fs-sm); }
.section .section-summary {
  color: var(--sub);
  font-size: var(--fs-sm);
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.section .move { display: flex; gap: var(--sp-1); flex: none; }
/* The arrows are for the row the pointer is on; they stay reachable by
   keyboard, so this hides noise without hiding function. */
@media (hover: hover) {
  .section .move { opacity: 0; transition: opacity .12s ease; }
  .section:hover .move,
  .section .move:focus-within { opacity: 1; }
}

/* --- the open section's form ----------------------------------------- */

form.open { padding: var(--sp-5); gap: var(--sp-4); }
form.open > .row:first-child { padding: 0 0 var(--sp-2); border-bottom: 1px solid var(--line-2); }
form.open .form-title { font-size: var(--fs-md); font-weight: 650; letter-spacing: -0.015em; }
form.open .save-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line-2);
}
form.open .save-bar .rest { display: flex; gap: var(--sp-4); align-items: center; margin-left: auto; }

/* --- the rich-text toolbar ------------------------------------------- */

/* Built by `editor.js` and inserted above each richtext area. */
.fmt { display: flex; gap: var(--sp-1); flex-wrap: wrap; }
.fmt button {
  font: inherit;
  font-size: var(--fs-xs);
  font-weight: 550;
  padding: var(--sp-1) var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--bg);
  color: var(--sub);
  cursor: pointer;
}
.fmt button:hover { color: var(--ink); border-color: var(--faint); background: var(--panel); }
/* The label wraps both the toolbar and the field, so the two need the same
   gap the rest of a label has and no more. */
label:has(> .fmt) { gap: var(--sp-2); }

/* The save confirmation, which doubles as Undo's home for sixty seconds. */
.notice.saved {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  background: var(--ok-soft);
  border-color: var(--ok-line);
  color: var(--ok);
  margin: 0;
}
.notice.saved .muted { color: inherit; opacity: 0.75; }
.notice.saved .btn-link { color: inherit; }

/* --- the preview ----------------------------------------------------- */

.preview { display: grid; gap: var(--sp-3); }
.preview .preview-head { display: flex; align-items: center; gap: var(--sp-3); }
.preview .preview-head strong { font-size: var(--fs-sm); font-weight: 650; }
.preview-frame {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--bg);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.preview-frame iframe {
  display: block;
  width: 100%;
  height: 38rem;
  border: 0;
  background: var(--bg);
}
@media (min-width: 64em) {
  .preview-frame iframe { height: calc(100vh - var(--header-h) - 9rem); }
}

/* --- theme swatches --------------------------------------------------- */

form.themes { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.theme-swatch {
  font: inherit;
  display: grid;
  gap: var(--sp-2);
  justify-items: center;
  padding: var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--bg);
  cursor: pointer;
  font-size: var(--fs-sm);
  font-weight: 550;
  color: var(--sub);
  transition: border-color .12s ease, color .12s ease;
}
.theme-swatch:hover { border-color: var(--faint); color: var(--ink); }
.theme-swatch[aria-pressed="true"] {
  border-color: var(--accent);
  color: var(--ink);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.theme-swatch .swatch-chips { display: flex; }
.theme-swatch .chip {
  width: 1.5rem; height: 1.5rem;
  border: 1px solid rgb(20 17 43 / 0.12);
}
.theme-swatch .chip:first-child { border-radius: var(--r-sm) 0 0 var(--r-sm); }
.theme-swatch .chip:last-child  { border-radius: 0 var(--r-sm) var(--r-sm) 0; }
.theme-swatch .chip + .chip { border-left: 0; }

/* --- the photo library ------------------------------------------------ */

/* One chip per photo, labelled with the words it was described with. */
.chips {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-4);
  padding: 0;
}
.chips li {
  font-size: var(--fs-xs);
  color: var(--sub);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  padding: 0.15rem var(--sp-3);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A titled block inside the editor's left column. */
.panel-block h2 { margin: 0 0 var(--sp-2); font-size: var(--fs-base); }
.panel-block > p { margin: 0 0 var(--sp-4); }

/* ==================================================================== */
/* The import flow                                                      */
/* ==================================================================== */

/* Four doors, each its own card, so a paste and a zip are visibly separate
   choices rather than one long form with headings in it. */
.doors { display: grid; gap: var(--sp-4); margin: 0 0 var(--sp-5); }
.door { display: grid; gap: var(--sp-3); }
.door h2 { margin: 0; font-size: var(--fs-base); }
.door p { margin: 0; font-size: var(--fs-sm); color: var(--sub); }
.door textarea { min-height: 9rem; font-family: var(--mono); font-size: var(--fs-sm); }

.findings { list-style: none; margin: 0 0 var(--sp-5); padding: 0; display: grid; gap: var(--sp-2); }
.findings li {
  display: flex;
  gap: var(--sp-3);
  align-items: flex-start;
  font-size: var(--fs-sm);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--bg);
}
.findings li::before {
  content: "";
  width: 0.4rem; height: 0.4rem;
  margin-top: 0.5rem;
  border-radius: var(--r-pill);
  background: var(--faint);
  flex: none;
}
.findings.good li::before { background: var(--ok); }
.findings.changed li::before { background: var(--warn); }
.findings.lost li::before { background: var(--danger); }

/* The decision at the end of the review: two buttons, weighted. */
.decide {
  display: flex;
  gap: var(--sp-3);
  align-items: center;
  flex-wrap: wrap;
  padding: var(--sp-5);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-lg);
  background: var(--accent-soft);
  margin: var(--sp-6) 0 var(--sp-4);
}
.decide form { display: contents; }

/* ==================================================================== */
/* Admin                                                                */
/* ==================================================================== */

.request-list { list-style: none; margin: 0 0 var(--sp-5); padding: 0; display: grid; gap: var(--sp-3); }

/* The referral tree. The rule is the line of descent, so it sits on the
   nested list rather than on each row. */
ul.tree { list-style: none; margin: 0; padding: 0; }
ul.tree ul {
  list-style: none;
  margin: var(--sp-2) 0 0;
  padding-left: var(--sp-4);
  border-left: 1px solid var(--line);
}
ul.tree li { margin: 0 0 var(--sp-2); font-size: var(--fs-sm); }
ul.tree li:last-child { margin-bottom: 0; }

/* The publish history's own bits. */
.publish-note {
  font-size: var(--fs-sm);
  color: var(--sub);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: var(--sp-4);
  margin-top: var(--sp-5);
}

/* ==================================================================== */
/* Utilities                                                            */
/* ==================================================================== */

.stack-sm { display: grid; gap: var(--sp-2); }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }

/* The honeypot field: off the canvas rather than display:none, which some
   bots know to skip. Never seen, never tabbed to, never announced. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ==================================================================== */
/* The site list                                                        */
/* ==================================================================== */

.site-list {
  list-style: none;
  margin: 0 0 var(--sp-5);
  padding: 0;
  display: grid;
  gap: var(--sp-3);
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
}
.site-card {
  display: grid;
  gap: var(--sp-2);
  padding: var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--bg);
  box-shadow: var(--shadow-sm);
  color: inherit;
  text-decoration: none;
  height: 100%;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.site-card:hover { border-color: var(--accent-line); box-shadow: var(--shadow); text-decoration: none; }
.site-card strong { font-size: var(--fs-md); font-weight: 650; letter-spacing: -0.015em; }
.site-card .host {
  font-family: var(--mono);
  font-size: var(--fs-sm);
  color: var(--sub);
  overflow-wrap: anywhere;
}

/* --- the domain wizard (#181) ---------------------------------------- */

/* A DNS record is a form somebody is copying into another window, so every
   value is monospaced, selectable as one piece, and allowed to break rather
   than push the card sideways on a phone. Nothing here is decoration: the
   customer is comparing two screens, and every character matters. */

.breakable { overflow-wrap: anywhere; }

.domain-free, .domain { margin: 0 0 var(--sp-4); }
.domain-free {
  display: grid;
  gap: var(--sp-2);
  justify-items: start;
  background: var(--panel);
}
.domain-free .host, .domain-state .host {
  font-family: var(--mono);
  font-size: var(--fs-md);
  overflow-wrap: anywhere;
}

/* The waiting panel. One row per domain, and the whole block is what the
   poll swaps - so it carries its own spacing rather than relying on a
   neighbour's margin that a swap could leave behind. */
#domain-states { display: grid; gap: var(--sp-2); margin: 0 0 var(--sp-4); }
.domain-state {
  display: grid;
  gap: var(--sp-1);
  grid-template-columns: auto 1fr;
  align-items: center;
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--bg);
}
.domain-state p { grid-column: 1 / -1; }
.domain-state.ok    { border-color: var(--ok-line);   background: var(--ok-soft); }
.domain-state.stuck { border-color: var(--warn-line); background: var(--warn-soft); }

/* One record at a time (DESIGN §9). The number down the left is the point of
   the ordered list - "the second one" is how somebody refers to these on the
   phone - so the marker stays visible rather than being replaced by a tick. */
ol.records {
  list-style: decimal;
  margin: var(--sp-4) 0 0;
  padding-left: var(--sp-5);
  display: grid;
  gap: var(--sp-4);
}
ol.records > li { padding-left: var(--sp-1); }

.record {
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: var(--sp-4);
  background: var(--panel);
}

/* The checkbox is the customer's own place-keeping and sits above the record
   rather than inside it, so it never reads as part of what they must type. */
.record-done {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--sub);
  margin: 0 0 var(--sp-2);
  cursor: pointer;
}
.record-done input { margin: 0; }

.record-fields {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-2) var(--sp-4);
  margin: 0;
  align-items: baseline;
}
.record-fields dt {
  font-size: var(--fs-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--sub);
}
.record-fields dd {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2);
  min-width: 0;
}
.record-fields .code { font-size: var(--fs-base); letter-spacing: 0.04em; }

/* A phone is where somebody actually does this, with the registrar's panel in
   the other tab. Two columns of labels there costs more width than the values
   can spare. */
@media (max-width: 30rem) {
  .record-fields { grid-template-columns: 1fr; gap: var(--sp-1); }
  .record-fields dt { margin-top: var(--sp-2); }
}

/* ==================================================================== */
/* The enquiry inbox (#45)                                              */
/* ==================================================================== */

/* Somebody else's words, in the owner's console. Nothing here is markup —
   every value is autoescaped by the template — so the only job of this block
   is to make a message readable and a spam card obviously set aside. */
.enquiry { display: flex; flex-direction: column; gap: var(--sp-2); }

/* Faded rather than hidden: the whole argument for keeping a honeypot hit is
   that a real enquiry wrongly flagged is still findable. */
.enquiry.spam { border-style: dashed; }
.enquiry.spam .message, .enquiry.spam .fields { color: var(--sub); }

.enquiry .fields {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--sp-1) var(--sp-3);
  margin: 0;
  align-items: baseline;
}
.enquiry .fields dt {
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--sub);
  min-width: 0;
  overflow-wrap: anywhere;
}
.enquiry .fields dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }

/* `pre-wrap`, so the paragraphs somebody typed survive, and `anywhere`, so a
   pasted URL with no spaces in it cannot widen the page. */
.enquiry .message {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  padding: var(--sp-3);
  border-radius: var(--r-sm);
  background: var(--panel-2);
}

/* The name column would otherwise take half the width on a phone. */
@media (max-width: 30rem) {
  .enquiry .fields { grid-template-columns: 1fr; gap: 0; }
  .enquiry .fields dt { margin-top: var(--sp-2); }
}
