/* ============================================================================
   ARK Workbook Studio — dark theme
   ----------------------------------------------------------------------------
   Three ideas hold this file together:

   1. Every colour lives in a custom property on :root. Nothing below hard-codes
      a hex. Change the theme in one place, the whole app follows.

   2. `color-scheme: dark` tells the browser to draw its OWN widgets dark —
      checkboxes, select drop-downs, scrollbars, the file-picker button, focus
      rings. Without it you get a dark page with blinding white native controls.

   3. The rotating border is one registered custom property (--ark-angle) that
      every ringed surface reads. One animation definition, reused everywhere.
   ========================================================================== */


/* --- 1. The animated angle -------------------------------------------------
   A plain custom property is just a string, so the browser can't interpolate
   between 0deg and 360deg — it would snap. @property registers the property
   with a real type, so it becomes animatable. This is the whole trick.
   -------------------------------------------------------------------------- */
@property --ark-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

@keyframes ark-rotate {
  to { --ark-angle: 360deg; }
}


/* --- 2. Tokens ------------------------------------------------------------ */
:root {
  /* Fallback for browsers without @property support: the gradient still
     renders, it just sits still instead of rotating. */
  --ark-angle: 0deg;

  --bg:        #0a0e13;
  --surface:   #121a23;
  --surface-2: #18222d;
  --surface-3: #1f2b38;
  --line:      #27333f;

  --text:      #eef4fa;
  --muted:     #adbdcd;

  --accent:    #4da3ff;
  --accent-2:  #8b5cf6;
  --accent-3:  #2dd4a7;
  --danger:    #ff6b6b;
  --warn:      #f0b429;

  /* The three stops of the rotating ring. */
  --g1: #4da3ff;
  --g2: #8b5cf6;
  --g3: #2dd4a7;

  --radius: 10px;
  --radius-sm: 7px;

  /* Century Gothic ships with Microsoft Office, so on a Windows box the real
     font is used. The rest are progressively looser geometric-sans fallbacks
     for machines (and the Linux server) that don't have it. */
  --font: "Century Gothic", "Questrial", "Didact Gothic", "URW Gothic",
          "Avant Garde", "Futura", "Trebuchet MS", "Segoe UI", sans-serif;

  color-scheme: dark;
}


/* --- 3. Base -------------------------------------------------------------- */
* { box-sizing: border-box; }

body {
  font-family: var(--font);
  font-weight: 400;
  letter-spacing: 0.01em;   /* geometric sans faces read better slightly open */
  margin: 0;
  padding-bottom: 60px;
  background:
    radial-gradient(900px 500px at 15% -10%, rgba(77,163,255,0.10), transparent 60%),
    radial-gradient(700px 500px at 95% 0%, rgba(139,92,246,0.09), transparent 60%),
    var(--bg);
  background-attachment: fixed;
  color: var(--text);
  font-size: 14px;
  line-height: 1.55;
}

h1, h2, h3, h4 { font-weight: 700; letter-spacing: 0.02em; }
strong, b { font-weight: 700; }
a { color: var(--accent); }
code {
  font-family: "Cascadia Mono", Consolas, monospace;
  background: var(--surface-3);
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 12px;
}
.hidden { display: none !important; }
.hint { color: var(--muted); font-size: 13px; }


/* --- 4. The rotating gradient ring ----------------------------------------
   Two backgrounds on one element:
     • a flat fill clipped to the PADDING box (the inside of the element)
     • the conic gradient clipped to the BORDER box (the 1px frame)
   The border itself is transparent, so the gradient shows through it. No
   pseudo-elements, no wrapper divs, and it follows border-radius for free.

   Applied to card-like surfaces and buttons only — putting it on every single
   <div> (.row, .q-item, table cells) would be visual noise and would repaint
   dozens of layers per frame for no gain.
   -------------------------------------------------------------------------- */
.panel,
.plan-box,
.config-sidebar,
.config-detail,
.scroll-box,
.chip,
button,
.btn,
input:not([type="checkbox"]):not([type="radio"]),
select,
textarea {
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background:
    linear-gradient(var(--surface-2), var(--surface-2)) padding-box,
    conic-gradient(from var(--ark-angle), var(--g1), var(--g2), var(--g3), var(--g1)) border-box;
  animation: ark-rotate 14s linear infinite;
}

/* Panels are the big surfaces: darker fill, rounder, slower ring. */
.panel {
  margin: 0 0 18px;
  padding: 20px 24px;
  border-radius: var(--radius);
  background:
    linear-gradient(var(--surface), var(--surface)) padding-box,
    conic-gradient(from var(--ark-angle), var(--g1), var(--g2), var(--g3), var(--g1)) border-box;
  animation-duration: 20s;
  box-shadow: 0 10px 30px rgba(0,0,0,0.35);
}
.panel h2 {
  margin: 0 0 6px;
  font-size: 16px;
  color: var(--text);
}
.panel h3 { font-size: 14px; margin: 18px 0 6px; }
.panel h4 { font-size: 13px; margin: 16px 0 6px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; }
.wide-panel { max-width: none; }

/* Someone who has asked their OS to stop moving things gets a static ring. */
@media (prefers-reduced-motion: reduce) {
  .panel, .plan-box, .config-sidebar, .config-detail, .scroll-box,
  .chip, button, .btn, input, select, textarea { animation: none; }
}


/* --- 5. Top bar ----------------------------------------------------------- */
.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 28px;
  background: rgba(10, 14, 19, 0.75);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 20;
}
.topbar h1 {
  font-size: 17px;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  background: linear-gradient(90deg, var(--g1), var(--g2), var(--g3));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.topbar h1 .icn { color: var(--accent); width: 20px; height: 20px; }
#who { color: var(--muted); font-size: 13px; }
.topbar-account { display: flex; align-items: center; justify-content: flex-end; gap: 10px; flex-wrap: wrap; }
.auth-link-button {
  display: inline-flex;
  margin-top: 10px;
  padding: 2px 0;
  border: 0;
  background: transparent;
  color: var(--accent);
  animation: none;
  box-shadow: none;
  text-decoration: none;
}
.auth-link-button:hover {
  background: transparent;
  color: var(--accent-3);
  animation: none;
  box-shadow: none;
  transform: none;
  text-decoration: underline;
}

/* ARK:v12 2026-09-18 — matched to ARK OPERA Configurator's Manage Users
   modal: fixed overlay, fixed header, scroll-owned body/table and responsive
   two-column account form. Workbook Studio theme tokens supply the colours. */
#manage-users-modal {
  position: fixed;
  inset: 0;
  z-index: 3000;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(8px, 2vw, 24px);
  overflow: hidden;
  background: rgba(0, 0, 0, 0.62);
  backdrop-filter: blur(5px);
}
#forgot-password-modal {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(8px, 2vw, 24px);
  background: rgba(0, 0, 0, 0.62);
  backdrop-filter: blur(5px);
}
#forgot-password-modal .auth-recovery-dialog { width: min(620px, 94vw); }
#manage-users-modal .user-admin-dialog {
  width: min(1080px, 94vw);
  max-width: 100%;
  max-height: calc(100dvh - clamp(16px, 4vw, 48px));
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 16px;
  background:
    linear-gradient(var(--surface), var(--surface)) padding-box,
    conic-gradient(from var(--ark-angle), var(--g1), var(--g2), var(--g3), var(--g1)) border-box;
  animation: ark-rotate 22s linear infinite;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.48), 0 0 28px rgba(77, 163, 255, 0.14);
}
#forgot-password-modal .user-admin-dialog {
  max-height: calc(100dvh - clamp(16px, 4vw, 48px));
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 16px;
  background:
    linear-gradient(var(--surface), var(--surface)) padding-box,
    conic-gradient(from var(--ark-angle), var(--g1), var(--g2), var(--g3), var(--g1)) border-box;
  animation: ark-rotate 22s linear infinite;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.48), 0 0 28px rgba(77, 163, 255, 0.14);
}
#manage-users-modal .user-admin-header,
#forgot-password-modal .user-admin-header,
#manage-users-modal .user-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
#manage-users-modal .user-admin-header {
  flex: 0 0 auto;
  z-index: 4;
  padding: 22px 26px;
  background: rgba(10, 14, 19, 0.88);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(18px);
}
#forgot-password-modal .user-admin-header {
  flex: 0 0 auto;
  padding: 22px 26px;
  background: rgba(10, 14, 19, 0.88);
  border-bottom: 1px solid var(--line);
}
#manage-users-modal .user-admin-header h3,
#manage-users-modal .user-admin-body h3,
#forgot-password-modal h3 { margin: 0; }
#manage-users-modal .user-admin-header-actions { display: flex; align-items: center; gap: 8px; }
#manage-users-modal .user-admin-body {
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
  padding: 24px 26px 28px;
}
#forgot-password-modal .user-admin-body { overflow-y: auto; padding: 24px 26px 28px; }
#manage-users-modal .user-admin-eyebrow {
  margin-bottom: 3px;
  color: var(--accent);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
#forgot-password-modal .user-admin-eyebrow { color: var(--accent); font-size: 11px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; }
#manage-users-modal .user-admin-subtitle,
#manage-users-modal .user-create-copy,
#forgot-password-modal .user-admin-subtitle,
#forgot-password-modal .user-create-copy,
#forgot-password-modal .user-form-hint { color: var(--muted); }
#manage-users-modal .user-admin-subtitle { margin: 4px 0 0; }
#forgot-password-modal .user-admin-subtitle { margin: 4px 0 0; }
#manage-users-modal .user-create-section {
  margin-top: 20px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: linear-gradient(135deg, rgba(77, 163, 255, 0.10), transparent 60%);
}
#forgot-password-modal .user-create-section { padding: 20px; border: 1px solid var(--line); border-radius: 12px; background: linear-gradient(135deg, rgba(77, 163, 255, 0.10), transparent 60%); }
#manage-users-modal .user-create-section h3 { margin-bottom: 4px; }
#manage-users-modal .user-create-copy { margin: 0 0 16px; }
#manage-users-modal .user-admin-table-wrap {
  max-width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  border: 1px solid var(--line);
  border-radius: 8px;
  margin-top: 20px;
  background: var(--surface);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.20);
}
#manage-users-modal .user-admin-table-wrap table { min-width: 760px; margin-top: 0; border-radius: 0; overflow: visible; }
#manage-users-modal th { position: sticky; top: 0; z-index: 2; background: rgba(31, 43, 56, 0.96); }
#manage-users-modal tbody tr { transition: background-color 0.18s ease; }
#manage-users-modal tbody tr:hover { background: rgba(77, 163, 255, 0.08); }
#manage-users-modal .user-status {
  display: inline-block;
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(45, 212, 167, 0.11);
  color: var(--accent-3);
  white-space: nowrap;
}
#manage-users-modal .user-status.disabled { background: rgba(255, 107, 107, 0.12); color: var(--danger); }
#manage-users-modal .user-role-select { min-width: 120px; padding: 6px 8px; }
#manage-users-modal .user-actions { flex-wrap: wrap; }
#manage-users-modal td:last-child { min-width: 210px; }
#manage-users-modal .user-form-error { min-height: 18px; margin-bottom: 8px; color: var(--danger); font-size: 12px; }
#manage-users-modal .user-form-hint { color: var(--muted); font-size: 12px; }
#manage-users-modal .user-create-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 16px; }
#manage-users-modal .form-group { display: flex; flex-direction: column; gap: 6px; }
#manage-users-modal .form-group input,
#manage-users-modal .form-group select { width: 100%; }
@media (max-width: 720px) {
  .topbar { align-items: flex-start; gap: 12px; }
  .topbar-account { justify-content: flex-start; }
  #manage-users-modal { padding: 8px; }
  #manage-users-modal .user-admin-dialog { max-height: calc(100dvh - 16px); border-radius: 12px; }
  #manage-users-modal .user-create-grid { grid-template-columns: 1fr; }
  #manage-users-modal .user-admin-header { align-items: flex-start; padding: 16px 18px; }
  #manage-users-modal .user-admin-body { padding: 18px; }
  #manage-users-modal .user-create-section { padding: 16px; }
}
@media (max-height: 700px) {
  #manage-users-modal .user-admin-header { padding-top: 14px; padding-bottom: 14px; }
  #manage-users-modal .user-admin-body { padding-top: 16px; padding-bottom: 18px; }
}


/* --- 6. Form controls ----------------------------------------------------- */
input:not([type="checkbox"]):not([type="radio"]), select, textarea {
  padding: 8px 11px;
  font: inherit;
  font-size: 14px;
  font-weight: 400;
  color: var(--text);
  animation-duration: 22s;   /* calmer than the buttons, they're not the focus */
}
input::placeholder, textarea::placeholder { color: #8194a6; }
textarea { width: 100%; resize: vertical; }

input:not([type="checkbox"]):not([type="radio"]):focus, select:focus, textarea:focus {
  outline: none;
  background:
    linear-gradient(var(--surface-3), var(--surface-3)) padding-box,
    conic-gradient(from var(--ark-angle), var(--g1), var(--g2), var(--g3), var(--g1)) border-box;
  box-shadow: 0 0 0 3px rgba(77,163,255,0.20);
}

/* Nothing but size and tint — no background, no border, no animation. Left
   native, the browser draws it dark because of color-scheme: dark on :root. */
input[type="checkbox"] {
  width: 15px;
  height: 15px;
  accent-color: var(--accent);
  vertical-align: -2px;
  cursor: pointer;
}

/* The open dropdown list is drawn by the browser, not by this stylesheet, and
   on Windows Chrome it paints that popup WHITE while still applying the
   author's `color` to the options — which is how light-on-white, effectively
   invisible options happen even with color-scheme: dark set. Styling <option>
   explicitly is the only thing that reaches inside that popup. */
select option {
  background-color: var(--surface-2);
  color: var(--text);
}
select option:checked,
select option:hover {
  background-color: var(--accent);
  color: #05121f;
}

input[type="file"] { padding: 5px 8px; }
input[type="file"]::file-selector-button {
  font: inherit;
  font-size: 13px;
  margin-right: 10px;
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface-3);
  color: var(--text);
  cursor: pointer;
}
input[type="file"]::file-selector-button:hover { background: #263547; }

select { min-width: 170px; }
label { font-size: 13px; }
.row { display: flex; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; align-items: center; }


/* --- 7. Buttons ----------------------------------------------------------
   One base style, three variants (.btn-ghost, .btn-danger, .btn-quiet) and one
   size modifier (.btn-sm). Every button gets an icon on the left; the icon is
   an <svg><use> pointing at the sprite in index.html, so it inherits
   currentColor and stays crisp at any zoom.
   -------------------------------------------------------------------------- */
button, .btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 15px;
  font: inherit;
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
  animation-duration: 9s;
  transition: transform 0.12s ease, box-shadow 0.2s ease, color 0.2s ease;
}
button:hover, .btn:hover {
  color: #fff;
  background:
    linear-gradient(var(--surface-3), var(--surface-3)) padding-box,
    conic-gradient(from var(--ark-angle), var(--g1), var(--g2), var(--g3), var(--g1)) border-box;
  animation-duration: 2.5s;             /* ring speeds up under the cursor */
  box-shadow: 0 6px 18px rgba(77,163,255,0.18);
  transform: translateY(-1px);
}
button:active, .btn:active { transform: translateY(0); }
button:focus-visible, .btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
button:disabled { opacity: 0.45; cursor: not-allowed; animation: none; transform: none; }

.icn {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Primary — the one action the section is really about. */
.btn-primary {
  color: #05121f;
  background:
    linear-gradient(135deg, var(--g1), var(--g3)) padding-box,
    conic-gradient(from var(--ark-angle), #fff, var(--g2), var(--g3), #fff) border-box;
}
.btn-primary:hover {
  color: #05121f;
  background:
    linear-gradient(135deg, #6bb4ff, #4ee0b8) padding-box,
    conic-gradient(from var(--ark-angle), #fff, var(--g2), var(--g3), #fff) border-box;
}

.btn-danger { color: var(--danger); }
.btn-danger:hover {
  color: #fff;
  background:
    linear-gradient(#3a1c1f, #3a1c1f) padding-box,
    conic-gradient(from var(--ark-angle), var(--danger), var(--g2), var(--danger)) border-box;
  box-shadow: 0 6px 18px rgba(255,107,107,0.18);
}

.btn-sm { padding: 5px 10px; font-size: 12.5px; }
.btn-sm .icn { width: 14px; height: 14px; }

/* Icon-only buttons: no label, so square them off and label them for
   screen readers with aria-label in the markup. */
.btn-icon { padding: 5px; border-radius: 50%; gap: 0; }

.btn-row { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }


/* --- 8. Tables ------------------------------------------------------------ */
table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 10px;
  font-size: 13px;
  background: var(--surface);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
th, td { border-bottom: 1px solid var(--line); padding: 7px 10px; text-align: left; }
th { font-weight: 700; }
td { font-weight: 400; }
th {
  background: var(--surface-3);
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.scroll-box th, .config-sidebar th, .grid-scroll th, .table-scroll th { position: sticky; top: 0; z-index: 3; }
tbody tr:hover { background: rgba(77,163,255,0.06); }
td input[type="text"] { padding: 4px 8px; font-size: 12.5px; animation: none; }


/* --- 9. Boxes and chips --------------------------------------------------- */
.plan-box { padding: 14px 16px; margin-top: 12px; animation-duration: 11s; }
.scroll-box { max-height: 280px; overflow-y: auto; padding: 6px 10px; }
/* ARK:v3 2026-09-10 — every data table gets its own scrolling body. The
   MutationObserver in app.js wraps tables created by any screen, including
   future screens, so column headings never disappear with the page. */
.table-scroll { max-height: min(520px, 65vh); overflow: auto; margin-top: 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.table-scroll table { margin-top: 0; border-radius: 0; overflow: visible; border-collapse: separate; border-spacing: 0; }
.table-scroll thead { position: sticky; top: 0; z-index: 6; }

pre {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 10px 12px;
  max-height: 240px;
  overflow: auto;
  font-size: 12px;
  color: #b8ccdf;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px 4px 12px;
  margin: 3px 4px 3px 0;
  font-size: 13px;
  animation-duration: 16s;
}

.badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  padding: 2px 7px;
  border-radius: 10px;
  margin-left: 6px;
  text-transform: uppercase;
}
.badge-required { background: rgba(255,107,107,0.18); color: #ff9a9a; border: 1px solid rgba(255,107,107,0.35); }
.badge-controls { background: rgba(45,212,167,0.15); color: #6ee7c0; border: 1px solid rgba(45,212,167,0.35); }
.badge-count    { background: rgba(77,163,255,0.15); color: #93c6ff; border: 1px solid rgba(77,163,255,0.30); }

.env-badge {
  display: inline-block;
  font-size: 11px;
  padding: 2px 10px;
  border-radius: 10px;
  background: rgba(77,163,255,0.12);
  color: var(--accent);
  margin-left: 8px;
}


/* --- 10. Questionnaire ---------------------------------------------------- */
.q-item { margin-bottom: 12px; }
.q-item > label { display: block; margin-bottom: 5px; color: var(--text); }
.q-item input:not([type="checkbox"]), .q-item select { width: 100%; }


/* --- 11. Section 5: config item sidebar + detail --------------------------
   The ~90 sidebar rows deliberately do NOT get the rotating ring. Ninety
   animated conic gradients in one scroll container is a repaint storm, and it
   would bury the one thing that matters here — which item is selected. They
   get a left accent bar instead.
   -------------------------------------------------------------------------- */
.config-items-layout { display: flex; gap: 18px; align-items: flex-start; }
.config-sidebar-shell { width: 320px; flex-shrink: 0; }
.config-sidebar {
  width: 320px;
  max-height: 640px;
  overflow-y: auto;
  padding: 0;
  animation-duration: 18s;
}
.config-item-search { width: 100%; margin-bottom: 8px; }
.config-search-count { min-height: 18px; margin: 6px 2px 0; }
.config-category.is-filtered-empty { display: none; }
.library-template-row { margin-top: 10px; }
.library-template-row select { min-width: 260px; flex: 1; }
.config-sidebar h3 {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  background: var(--surface-3);
  margin: 0;
  padding: 7px 12px;
  position: sticky;
  top: 0;
  z-index: 2;
}
.config-item-btn {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  background: transparent;
  color: var(--text);
  border: none;
  border-left: 3px solid transparent;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  padding: 8px 12px;
  font-size: 13px;
  font-weight: 400;
  animation: none;
  transform: none;
  box-shadow: none;
}
.config-item-btn:hover {
  background: rgba(77,163,255,0.08);
  border-left-color: var(--accent-2);
  box-shadow: none;
  transform: none;
  color: var(--text);
  animation: none;
}
.config-item-btn.active {
  background: rgba(77,163,255,0.14);
  border-left-color: var(--accent);
  color: #fff;
  font-weight: 700;
}
.config-item-btn .ci-name { flex: 1; min-width: 0; }
.config-item-btn .badge { margin-left: 0; }

.config-detail { flex: 1; min-width: 0; padding: 16px 18px; animation-duration: 18s; }
.config-detail h3 { margin-top: 0; }

.recommended-grid table { min-width: max-content; margin: 0; }
.recommended-grid th, .recommended-grid td { white-space: nowrap; font-size: 13px; }
.recommended-grid-row:hover { background: rgba(77,163,255,0.06); }
.recommended-grid-row.selected { background: rgba(45,212,167,0.10); }
.recommended-check-col { width: 54px; min-width: 54px; text-align: center; }


/* --- 12. Login ------------------------------------------------------------ */
#loginScreen { max-width: 400px; margin: 80px auto; }
#loginScreen input { width: 100%; margin-bottom: 10px; }
#loginScreen button { width: 100%; justify-content: center; }


/* --- 13. Scrollbars ------------------------------------------------------- */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: 10px; border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: #33455a; }


/* --- 14. App shell: left nav + one view at a time -------------------------
   The whole app used to be one scrolling page. It isn't any more: every
   screen is a .view, all of them are in the DOM, and exactly one carries
   .active at a time. app.js toggles that class and nothing else.

   Why keep them all in the DOM rather than build each screen on demand?
   Because the state already lives in module-level variables in app.js
   (currentProjectId, currentConfigItemKey). Re-rendering a screen from
   scratch on every visit would mean re-fetching data the app already has.
   Show/hide is the cheaper and simpler answer at this size.
   -------------------------------------------------------------------------- */
.shell {
  display: flex;
  align-items: flex-start;
  gap: 0;
  min-height: calc(100vh - 56px);
}

.ark-nav {
  width: 236px;
  flex-shrink: 0;
  position: sticky;
  top: 56px;
  align-self: flex-start;
  max-height: calc(100vh - 56px);
  overflow-y: auto;
  padding: 16px 12px 30px;
  border-right: 1px solid var(--line);
  background: rgba(10, 14, 19, 0.5);
}

.nav-group-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #8194a6;
  padding: 16px 10px 6px;
}
.nav-group-label:first-child { padding-top: 4px; }

/* Nav items are <button>, so they must opt OUT of the generic button styling
   above — no ring, no lift, no gradient. They are navigation, not actions. */
.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  padding: 8px 10px;
  margin-bottom: 2px;
  font-size: 13.5px;
  font-weight: 400;
  color: var(--muted);
  background: transparent;
  border: none;
  border-left: 3px solid transparent;
  border-radius: 6px;
  animation: none;
  box-shadow: none;
  transform: none;
}
.nav-item:hover {
  background: rgba(77,163,255,0.08);
  color: var(--text);
  box-shadow: none;
  transform: none;
  animation: none;
}
.nav-item.active {
  background: rgba(77,163,255,0.14);
  border-left-color: var(--accent);
  color: #fff;
  font-weight: 700;
}
.nav-item.active .icn { color: var(--accent); }
.nav-item .badge { margin-left: auto; }
.badge-soon {
  background: rgba(240,180,41,0.14);
  color: var(--warn);
  border: 1px solid rgba(240,180,41,0.30);
}

.workspace {
  flex: 1;
  min-width: 0;
  max-width: 1180px;
  padding: 22px 28px 60px;
}

/* Exactly one view is visible. */
.view { display: none; }
.view.active { display: block; animation: view-in 0.18s ease; }
@keyframes view-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}

.view-title { font-size: 20px; margin: 0 0 4px; }
.view-sub { color: var(--muted); font-size: 13px; margin: 0 0 20px; max-width: 90ch; }

/* Which project everything on screen is acting on. */
.context-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 9px 14px;
  margin-bottom: 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 13px;
}
.context-bar strong { color: var(--text); }
.context-bar .ctx-sep { color: var(--line); }

.callout {
  padding: 9px 13px;
  margin-bottom: 12px;
  border-left: 3px solid var(--accent);
  border-radius: 0 6px 6px 0;
  background: rgba(77,163,255,0.08);
  font-size: 13px;
  color: var(--muted);
}
.callout.ok { border-left-color: var(--accent-3); background: rgba(45,212,167,0.08); }
.callout.bad { border-left-color: var(--danger); background: rgba(255,107,107,0.08); }
.callout .callout-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

/* --- Preflight ------------------------------------------------------------
   A count of errors is a dead end; what a consultant needs is which row, what
   is wrong with it, and a way to get there. This panel is that list.
   -------------------------------------------------------------------------- */
.preflight-panel {
  margin-bottom: 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}
.preflight-toolbar {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  padding: 10px 13px;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
  font-size: 13px;
}
.preflight-toolbar .spacer { flex: 1; }
.preflight-group { border-bottom: 1px solid var(--line); }
.preflight-group:last-child { border-bottom: 0; }
.preflight-group > summary {
  cursor: pointer; padding: 9px 13px; font-weight: 700;
  display: flex; align-items: center; gap: 10px;
}
.preflight-group > summary::-webkit-details-marker { display: none; }
.preflight-group > summary::before { content: '▸'; color: var(--muted); }
.preflight-group[open] > summary::before { content: '▾'; }
.preflight-group > summary:hover { background: var(--surface-2); }
.preflight-count { font-weight: 400; color: var(--muted); font-size: 12px; }
.preflight-list { list-style: none; margin: 0; padding: 0 0 6px; }
.preflight-item {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 7px 13px 7px 30px;
  border-top: 1px solid var(--line);
  font-size: 13px;
}
.preflight-item .who { min-width: 170px; color: var(--text); font-weight: 700; word-break: break-word; }
.preflight-item .what { flex: 1; color: var(--muted); }
.preflight-item .what .err { color: var(--danger); display: block; }
.preflight-item .what .wrn { color: var(--warn); display: block; }

/* The row a consultant just jumped to, so it is obvious which one of 200 was
   meant. Fades rather than latching, so it does not linger as false state. */
@keyframes ark-flash {
  from { background: rgba(240,180,41,0.35); }
  to   { background: transparent; }
}
.preflight-target > td, tr.preflight-target { animation: ark-flash 2.4s ease-out 1; }
@media (prefers-reduced-motion: reduce) {
  .preflight-target > td, tr.preflight-target { animation: none; outline: 2px solid var(--warn); }
}

/* A recommended code that is ticked but did not pass preflight. The tick alone
   would say "this is in the export" when it is not. */
.recommended-grid-row.held-back td:first-child { box-shadow: inset 3px 0 0 var(--warn); }

/* --- The rules, stated up front ------------------------------------------- */
.rules-panel {
  margin: 0 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}
.rules-panel > summary {
  cursor: pointer; padding: 9px 13px; font-weight: 700; font-size: 13px;
  display: flex; align-items: center; gap: 8px;
}
.rules-panel > summary::-webkit-details-marker { display: none; }
.rules-panel > summary .icn { width: 15px; height: 15px; color: var(--accent-3); }
.rules-panel > summary:hover { background: var(--surface-2); }
.rules-body { padding: 0 13px 10px; border-top: 1px solid var(--line); }
.rules-table { font-size: 12.5px; }
.rules-table td:first-child { white-space: nowrap; font-weight: 700; color: var(--text); }
.rules-table code {
  padding: 1px 5px; border-radius: 4px;
  background: var(--surface-3); color: var(--text); font-size: 11.5px;
}
.rule-star { color: var(--warn); }
.rule-must { color: var(--warn); font-weight: 700; }
.rule-id { color: var(--accent-2); font-weight: 700; }
.rule-warn { color: var(--danger); }
.rule-free { color: var(--muted); font-style: italic; }


.roadmap h3 { display: flex; align-items: center; gap: 9px; margin-top: 0; color: var(--warn); }
.roadmap h3 .icn { width: 18px; height: 18px; }
.roadmap p { max-width: 80ch; }

/* Below a laptop width the nav goes horizontal so it doesn't eat the screen. */
@media (max-width: 900px) {
  .shell { flex-direction: column; }
  .ark-nav {
    width: 100%;
    position: static;
    max-height: none;
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    border-right: none;
    border-bottom: 1px solid var(--line);
  }
  .nav-group-label { display: none; }
  .nav-item { width: auto; }
  .workspace { padding: 18px 16px 50px; }
  .config-items-layout { flex-direction: column; }
  .config-sidebar { width: 100%; max-height: 300px; }
}

/* --- 15. Questionnaire groups ---------------------------------------------
   37 questions in one flat column is a wall of inputs. Grouping by category
   with a sticky-ish heading turns it into eight short forms.
   -------------------------------------------------------------------------- */
.q-group { margin-bottom: 26px; }
.q-group h4 {
  margin: 0 0 12px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--line);
  color: var(--accent);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* The expected line format for a 'list' question, shown above the box rather
   than buried in placeholder text that vanishes the moment you type. */
.q-format {
  margin: 0 0 6px;
  padding: 7px 10px;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--muted);
  background: var(--bg);
  border: 1px dashed var(--line);
  border-radius: 5px;
  white-space: pre-wrap;
  max-height: none;
}
.q-item textarea { font-size: 13px; }

/* --- 16. Config item add-row form ----------------------------------------
   Label left, control right. The control is a dropdown wherever the value has
   to already exist somewhere, so the form itself is what prevents the typo.
   -------------------------------------------------------------------------- */
.field-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
}
.field-row > label {
  width: 240px;
  flex-shrink: 0;
  color: var(--muted);
  font-size: 12.5px;
}
/* Oracle's own asterisk means "the import will reject this row without it". */
.field-row > label.field-required { color: var(--text); font-weight: 700; }
.field-row > label.field-required::before {
  content: '';
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-right: 7px;
  border-radius: 50%;
  background: var(--danger);
  vertical-align: middle;
}
.field-control { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.field-control > input, .field-control > select { flex: 1; min-width: 160px; }
.field-control select[multiple] { padding: 4px; min-height: 84px; }
.field-note { font-size: 12px; }
select:disabled { opacity: 0.6; cursor: not-allowed; }

/* --- 17. Autosave status + presets ---------------------------------------
   The indicator is not decoration. A consultant filling a 38-question intake
   over three days needs to see that closing the tab is safe, and needs to be
   told loudly when it isn't.
   -------------------------------------------------------------------------- */
.save-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 11px;
  margin-bottom: 12px;
  border-radius: 20px;
  font-size: 12px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--muted);
}
.save-status::before {
  content: '';
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--muted);
}
.save-status.ok { color: var(--accent-3); border-color: rgba(45,212,167,0.35); }
.save-status.ok::before { background: var(--accent-3); }
.save-status.pending { color: var(--warn); border-color: rgba(240,180,41,0.35); }
.save-status.pending::before { background: var(--warn); }
.save-status.bad { color: var(--danger); border-color: rgba(255,107,107,0.4); }
.save-status.bad::before { background: var(--danger); }

.preset-btn { margin-top: 7px; }
.check-inline { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); font-size: 13px; }

/* --- 18. Select-all bar over the recommended checklist -------------------- */
.select-all-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 10px;
  margin-bottom: 6px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-3);
}
.select-all-bar .check-inline { color: var(--text); font-weight: 700; }

/* --- 19. Revenue centre cards -------------------------------------------- */
.centre-card {
  padding: 12px 14px;
  margin-bottom: 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.centre-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.centre-head strong { font-size: 14px; }
.centre-head .btn-icon { margin-left: auto; }
.centre-periods { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.period-chip {
  padding: 3px 10px;
  border: 1px solid var(--line);
  border-radius: 20px;
  font-size: 12.5px;
  background: var(--surface);
}
.period-chip.on { border-color: var(--accent); color: var(--text); background: rgba(77,163,255,0.12); }

/* --- 20. Row review state ------------------------------------------------
   A tick box that leads nowhere is worse than no tick box: it looks like it
   did something. These pills are the visible half of that — a row is draft
   until somebody marks it ready, and the export can be told to carry only the
   ready ones.
   -------------------------------------------------------------------------- */
.status-pill {
  display: inline-block;
  padding: 1px 9px;
  border-radius: 10px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border: 1px solid var(--line);
  background: var(--surface-3);
  color: var(--muted);
}
.status-pill.status-verified { background: rgba(45,212,167,0.15); color: #6ee7c0; border-color: rgba(45,212,167,0.35); }
.status-pill.status-exported { background: rgba(77,163,255,0.15); color: #93c6ff; border-color: rgba(77,163,255,0.30); }
.status-pill.status-edited   { background: rgba(240,180,41,0.14); color: var(--warn); border-color: rgba(240,180,41,0.30); }
tr.row-ready td { background: rgba(45,212,167,0.05); }

/* --- 21. Inline cell editing --------------------------------------------- */
/* ARK:v4 2026-09-10 — collapsed table borders and overflow:hidden on the
   table itself make sticky cells scroll away in Chromium. The scroll box now
   owns clipping; the table uses separate borders and its whole thead sticks. */
.grid-scroll {
  position: relative;
  max-height: min(460px, 62vh);
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  isolation: isolate;
}
.grid-scroll table {
  margin-top: 0;
  border-radius: 0;
  border-collapse: separate;
  border-spacing: 0;
  overflow: visible;
}
.grid-scroll thead { position: sticky; top: 0; z-index: 8; }
.grid-scroll thead th { position: static; background: var(--surface-3); box-shadow: 0 1px 0 var(--line); }

.editable-grid td.cell { cursor: text; }
.editable-grid td.cell:hover { background: rgba(77,163,255,0.10); box-shadow: inset 0 0 0 1px var(--accent); }
.cell-empty { color: #5f7183; }
.cell-input {
  width: 100%;
  min-width: 90px;
  padding: 3px 6px;
  font-size: 12.5px;
  animation: none;
}
/* A brief green flash is the whole acknowledgement an inline edit needs —
   anything more (a toast, a banner) interrupts the next edit. */
td.cell-saved { background: rgba(45,212,167,0.18) !important; transition: background 0.6s ease; }

/* --- 22. Recommended checklist filter ------------------------------------ */
.rec-filter { flex: 1; min-width: 180px; max-width: 320px; padding: 4px 10px; font-size: 12.5px; animation: none; }
.select-all-bar .rec-filter { margin: 0 10px; }
#recScroll .recommended-grid-row[hidden] { display: none !important; }

/* --- 23. The code structure, shown rather than described ----------------- */
.code-shape { margin: 10px 0 14px; }
.cs-part {
  display: inline-block;
  font-family: "Cascadia Mono", Consolas, monospace;
  font-size: 30px;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 4px 8px;
  border-radius: 6px;
}
.cs-centre { color: #93c6ff; background: rgba(77,163,255,0.14); }
.cs-period { color: #d3b6ff; background: rgba(139,92,246,0.16); }
.cs-item   { color: #6ee7c0; background: rgba(45,212,167,0.14); }
.cs-legend { display: flex; flex-direction: column; gap: 3px; margin-top: 10px; font-size: 12.5px; color: var(--muted); }
.cs-legend b { font-family: "Cascadia Mono", Consolas, monospace; padding: 0 4px; border-radius: 3px; }

.structure-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 18px; margin-top: 14px; }
.structure-grid h4 { margin: 0 0 6px; }
.structure-grid table { margin-top: 0; font-size: 12.5px; }
.structure-grid td { padding: 4px 8px; }

.unmapped-list { margin: 6px 0 0; padding-left: 20px; }
.unmapped-list li { margin: 3px 0; }
.cookie-fallback { margin: 0 0 10px; }
.cookie-fallback > summary { cursor: pointer; font-size: 12.5px; color: var(--muted); padding: 4px 0; }
.cookie-fallback > summary:hover { color: var(--text); }
