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

  :root {
    --bg: #0a0a0a;
    --surface: #141414;
    --surface2: #242424;
    --border: #333333;
    --primary: #ff4500;
    --primary-hover: #ce3800;
    --text: #cfcfcf;
    --muted: #8b8b8b;
    --success: #28a745;
    --error: #dc3545;
    --warning: #ffc107;
  }

  body {
    background: var(--bg);
    color: var(--text);
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-size: 15px;
    line-height: 1.6;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 2rem 1rem 4rem;
  }

  a {
    color: var(--primary);
    text-decoration: underline;
    text-underline-offset: 2px;
  }
  a:hover { color: var(--primary-hover); }
  a:visited { color: var(--primary); }

  header {
    text-align: center;
    margin-bottom: 2.5rem;
    position: relative;
    width: 100%;
    max-width: 640px;
  }

  header h1 {
    font-size: 1.8rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: #fff;
  }

  header p {
    color: var(--muted);
    margin-top: 0.4rem;
    font-size: 0.95rem;
  }

  .card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1.75rem;
    width: 100%;
    max-width: 640px;
  }

  .card + .card { margin-top: 1.25rem; }

  label {
    display: block;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 0.5rem;
  }

  input[type="text"], input[type="url"], input[type="password"], input[type="number"], input[type="file"], select {
    width: 100%;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--text);
    font-size: 0.95rem;
    padding: 0.65rem 0.9rem;
    outline: none;
    transition: border-color 0.15s;
  }

  /* Strip native chrome from <select> and paint our own chevron so it
     matches the dark surface and border tokens. background-image is a
     tiny inline SVG (no extra HTTP round-trip, no font dependency); the
     fill colour is the muted token so the arrow recedes until focus. */
  select {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    padding-right: 2.2rem;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none'><path d='M1 1l4 4 4-4' stroke='%23888' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-repeat: no-repeat;
    background-position: right 0.9rem center;
    cursor: pointer;
  }
  select:focus { border-color: var(--primary); }
  /* The native popup itself is browser-painted and only partially
     themable. These two properties improve readability on Chromium/
     Firefox where they're honoured; Safari ignores them and shows the
     system light popup regardless. */
  select option { background: var(--surface2); color: var(--text); }

  input[type="text"]:focus, input[type="url"]:focus, input[type="password"]:focus, input[type="number"]:focus {
    border-color: var(--primary);
  }

  /* Chrome/Safari paint autofilled fields with a baked-in light-blue
     background that ignores our dark-theme variables. Override with an
     inset shadow the size of the field - the standard hack - plus a
     text-fill-color so the text stays readable. The transition is the
     ride-the-out trick: autofill style lasts ~5000s, so deferring our
     style application by the same duration effectively cancels it. */
  input:-webkit-autofill,
  input:-webkit-autofill:hover,
  input:-webkit-autofill:focus,
  input:-webkit-autofill:active {
    -webkit-text-fill-color: var(--text);
    -webkit-box-shadow: 0 0 0 1000px var(--surface2) inset;
    box-shadow: 0 0 0 1000px var(--surface2) inset;
    caret-color: var(--text);
    transition: background-color 5000s ease-in-out 0s, color 5000s ease-in-out 0s;
  }

  /* Right-aligned compact import affordance. Sits in its own .field
     at the top of the form, but unlike the other fields the row is a
     flex container that pushes its single child to the right edge so
     the chip doesn't pretend to be a primary input. Same dashed-border
     surface treatment as the file-drop pickers below, just shrunk to
     button size so a first-time-build operator's eye flows past it. */
  .import-row { display: flex; justify-content: flex-end; margin-bottom: 1.25rem; }
  .import-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.45rem 0.85rem;
    background: var(--surface2);
    border: 1px dashed var(--border);
    border-radius: 8px;
    cursor: pointer;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--muted);
    text-transform: none;
    letter-spacing: 0;
    margin-bottom: 0;
    transition: border-color 0.15s, background 0.15s, color 0.15s;
  }
  .import-btn:hover { border-color: var(--primary); background: rgba(255,69,0,0.05); color: var(--text); }
  .import-btn .import-icon { color: var(--primary); flex-shrink: 0; }

  .file-drop {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    background: var(--surface2);
    border: 1px dashed var(--border);
    border-radius: 8px;
    padding: 0.65rem 0.9rem;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
    color: var(--muted);
    font-size: 0.9rem;
  }

  .file-drop:hover {
    border-color: var(--primary);
    background: rgba(255,69,0,0.05);
    color: var(--text);
  }

  .file-drop.has-file {
    border-style: solid;
    border-color: var(--border);
    color: var(--text);
  }

  .file-drop input[type="file"] {
    position: absolute;
    inset: 0;
    opacity: 0;
    width: 100%;
    height: 100%;
    cursor: pointer;
    font-size: 0;
  }

  .field { margin-bottom: 1.25rem; }
  .field:last-child { margin-bottom: 0; }

  .hint {
    font-size: 0.8rem;
    color: var(--muted);
    margin-top: 0.35rem;
  }

  .sign-options {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem;
  }

  .sign-option {
    position: relative;
  }

  .sign-option input[type="radio"] {
    position: absolute;
    opacity: 0;
    width: 0;
  }

  .sign-option label {
    display: flex;
    flex-direction: column;
    padding: 0.85rem 1rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    cursor: pointer;
    text-transform: none;
    letter-spacing: 0;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text);
    transition: border-color 0.15s, background 0.15s;
  }

  .sign-option label small {
    font-weight: 400;
    font-size: 0.78rem;
    color: var(--muted);
    margin-top: 0.2rem;
  }

  .sign-option input:checked + label {
    border-color: var(--primary);
    background: rgba(255,69,0,0.1);
  }

  #keystore-section {
    display: none;
    margin-top: 1.25rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--border);
  }

  #keystore-section.visible { display: block; }

  .row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }

  button[type="submit"] {
    width: 100%;
    background: var(--primary);
    color: #fff;
    border: none;
    border-radius: 8px;
    font-size: 1rem;
    font-weight: 600;
    padding: 0.8rem;
    cursor: pointer;
    transition: background 0.15s, opacity 0.15s;
    margin-top: 0.5rem;
  }

  button[type="submit"]:hover { background: var(--primary-hover); }
  button[type="submit"]:disabled { opacity: 0.5; cursor: not-allowed; }

  #status-card { display: none; }
  #status-card.visible { display: block; }

  .status-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
  }

  .badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.7rem;
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: 600;
  }

  .badge.queued  { background: rgba(136,136,170,0.15); color: var(--muted); }
  .badge.building { background: rgba(255,193,7,0.15); color: var(--warning); }
  .badge.done    { background: rgba(40,167,69,0.15); color: var(--success); }
  .badge.failed  { background: rgba(220,53,69,0.15); color: var(--error); }

  .spinner {
    width: 14px; height: 14px;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
    display: inline-block;
  }

  @keyframes spin { to { transform: rotate(360deg); } }

  .meta {
    font-size: 0.82rem;
    color: var(--muted);
    margin-top: 0.75rem;
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.25rem 0.75rem;
  }

  .meta strong { color: var(--text); min-width: 0; }
  /* Long values (package names, update codes) must wrap rather than
     push the grid wider than its container - overflow-wrap handles the
     atypical case where the value has no whitespace to break on. */
  .meta strong, .meta code { overflow-wrap: anywhere; word-break: break-all; }

  .error-msg {
    background: rgba(220,53,69,0.1);
    border: 1px solid rgba(220,53,69,0.3);
    border-radius: 8px;
    padding: 0.75rem 1rem;
    font-size: 0.85rem;
    color: var(--error);
    margin-top: 1rem;
    word-break: break-all;
  }

  .dedup-msg {
    background: rgba(255,193,7,0.08);
    border: 1px solid rgba(255,193,7,0.3);
    border-radius: 8px;
    padding: 0.9rem 1.15rem;
    font-size: 0.85rem;
    color: var(--muted);
    line-height: 1.5;
    margin-bottom: 0.75rem;
  }

  .update-ack {
    background: rgba(76,175,80,0.08);
    border: 1px solid rgba(76,175,80,0.3);
    border-radius: 8px;
    /* Vertical padding bumped from 0.65rem so the strong+running-text
       lines don't crowd the top/bottom border. Horizontal bumped to
       match. Margin gives breathing room above the badge row. */
    padding: 0.9rem 1.15rem;
    font-size: 0.85rem;
    color: var(--muted);
    line-height: 1.5;
    margin: 0.85rem 0;
  }
  .update-ack strong { color: var(--text); }

  .download-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background: var(--success);
    color: #fff;
    border: none;
    border-radius: 8px;
    font-size: 0.95rem;
    font-weight: 600;
    padding: 0.7rem 1.25rem;
    text-decoration: none;
    transition: opacity 0.15s;
  }

  .download-btn:hover { opacity: 0.88; }

  .download-btn-secondary {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text);
  }

  .download-row {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-top: 1.25rem;
  }

  /* Plain informational hint - matches .hint used elsewhere in the form
     (e.g. the self-signed keystore advisory). No alert chrome; debug
     and bayton notes are informational hints about the consequences of
     the picked sign mode, not warnings. */
  #bayton-note,
  #debug-note {
    display: none;
    margin-top: 0.75rem;
    font-size: 0.8rem;
    color: var(--muted);
    line-height: 1.5;
  }

  #bayton-note.visible,
  #debug-note.visible { display: block; }

  .site-logo {
    height: 2rem;
    width: auto;
    display: block;
    margin: 0 auto 0.5rem;
  }

  footer {
    margin-top: 3rem;
    font-size: 0.78rem;
    color: var(--muted);
    text-align: center;
  }

  /* Help button */
  .help-btn {
    position: absolute;
    top: 0;
    right: 0;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    border: 1.5px solid var(--border);
    background: none;
    color: var(--muted);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    font-weight: 700;
    font-family: inherit;
    transition: border-color 0.15s, color 0.15s;
    line-height: 1;
  }
  .help-btn:hover { border-color: var(--primary); color: var(--primary); }

  /* Docs modal */
  .modal-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.75);
    z-index: 100;
    align-items: center;
    justify-content: center;
    padding: 1rem;
  }
  .modal-backdrop.open { display: flex; }

  .modal {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    width: 100%;
    max-width: 600px;
    max-height: 85vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  .modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1.1rem 1.5rem;
    border-bottom: 1px solid var(--border);
    background: var(--surface);
    flex-shrink: 0;
  }
  .modal-header h2 { font-size: 1rem; font-weight: 700; color: #fff; }

  .modal-close {
    background: none;
    border: none;
    color: var(--muted);
    cursor: pointer;
    padding: 0.25rem;
    border-radius: 4px;
    display: flex;
    align-items: center;
    transition: color 0.15s;
  }
  .modal-close:hover { color: var(--text); }

  .modal-body {
    overflow-y: auto;
    padding: 1.5rem;
  }
  .modal-body section { margin-bottom: 1.75rem; }
  .modal-body section:last-child { margin-bottom: 0; }

  .modal-body h3 {
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--primary);
    margin-bottom: 0.65rem;
  }
  .modal-body p, .modal-body dd, .modal-body li {
    font-size: 0.875rem;
    color: var(--muted);
    line-height: 1.65;
    margin-bottom: 0.4rem;
  }
  .modal-body a {
    color: var(--primary);
    text-decoration: underline;
    text-decoration-color: rgba(255, 69, 0, 0.4);
    text-underline-offset: 2px;
  }
  .modal-body a:hover {
    color: var(--primary-hover);
    text-decoration-color: var(--primary-hover);
  }
  .modal-body dt {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--text);
    margin-top: 0.75rem;
    margin-bottom: 0.15rem;
  }
  .modal-body dt:first-child { margin-top: 0; }
  .modal-body ul { padding-left: 1.2rem; }
  .modal-body li { margin-bottom: 0.35rem; }

  /* Colour picker row */
  .colour-row {
    display: flex;
    align-items: stretch;
    gap: 0.5rem;
  }

  .colour-row input[type="text"] { flex: 1; }

  /* Visible swatch - a plain button so sizing is fully under our control */
  .colour-swatch {
    width: 2.75rem;
    flex-shrink: 0;
    border: 1px solid var(--border);
    border-radius: 8px;
    cursor: pointer;
    padding: 0;
    background: #ffffff;
    transition: border-color 0.15s;
  }

  .colour-swatch:hover { border-color: var(--primary); }

  /* Update code box */
  .update-box {
    background: rgba(255,193,7,0.08);
    border: 1px solid rgba(255,193,7,0.3);
    border-radius: 8px;
    padding: 1rem 1.1rem;
    margin-top: 1.25rem;
  }

  .update-box-label {
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--warning);
    margin-bottom: 0.45rem;
  }

  .update-code-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.6rem;
    min-width: 0; /* allow children to shrink below their content width */
  }

  .update-code {
    font-family: ui-monospace, 'Cascadia Code', 'Fira Mono', monospace;
    font-size: 0.88rem;
    color: #fff;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.5rem 0.75rem;
    flex: 1;
    min-width: 0; /* unblock flex shrinking past the intrinsic <code> width */
    overflow-wrap: anywhere;
    overflow-x: auto;
    white-space: nowrap;
    user-select: all;
  }

  .copy-btn {
    flex-shrink: 0;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    cursor: pointer;
    padding: 0.45rem 0.8rem;
    font-size: 0.82rem;
    font-family: inherit;
    font-weight: 600;
    transition: border-color 0.15s, color 0.15s;
  }

  .copy-btn:hover { border-color: var(--primary); color: var(--primary); }

  /* Toggle row - label left, switch right */
  .toggle-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.25rem 0;
    cursor: pointer;
    user-select: none;
    /* reset inherited label styles */
    text-transform: none;
    letter-spacing: 0;
    color: var(--text);
    font-weight: 600;
    font-size: 0.9rem;
  }
  .toggle-row:hover { color: var(--muted); }
  /* Visually hide the checkbox but keep it in the tab sequence and
     readable to assistive tech. `display:none` (WAG's original) drops
     it from the accessibility tree AND tab order, locking out keyboard
     and screenreader users entirely. */
  .toggle-row input[type="checkbox"] {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
    margin: 0;
  }
  /* Visible focus ring on the toggle-switch when the (invisible) input
     receives keyboard focus. :focus-visible suppresses it on mouse
     activation, matching browser defaults. */
  .toggle-row input[type="checkbox"]:focus-visible ~ .toggle-switch {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
  }
  /* The visual switch - pill with inline On/Off label and sliding knob */
  .toggle-switch {
    position: relative;
    flex-shrink: 0;
    width: 72px;
    height: 32px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
    transition: background 0.25s, border-color 0.25s;
  }
  /* Text label sits opposite the knob */
  .toggle-switch::before {
    content: 'Off';
    position: absolute;
    right: 10px;
    left: auto;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--muted);
    pointer-events: none;
    transition: color 0.2s;
  }
  /* Sliding knob */
  .toggle-switch::after {
    content: '';
    position: absolute;
    top: 3px;
    left: 3px;
    width: 24px;
    height: 24px;
    background: #fff;
    border-radius: 50%;
    box-shadow: 0 1px 4px rgba(0,0,0,0.4);
    transition: transform 0.25s cubic-bezier(0.4,0,0.2,1);
  }
  /* ON state: orange pill, label on the left, knob slides right */
  .toggle-row input:checked ~ .toggle-switch {
    background: var(--primary);
    border-color: var(--primary);
  }
  .toggle-row input:checked ~ .toggle-switch::before {
    content: 'On';
    left: 10px;
    right: auto;
    color: #fff;
  }
  .toggle-row input:checked ~ .toggle-switch::after {
    transform: translateX(40px);
  }

  /* Mobile */
  @media (max-width: 540px) {
    .sign-options { grid-template-columns: 1fr !important; }
    .row { grid-template-columns: 1fr; }
    body { padding: 1.5rem 0.75rem 3rem; }
    .card { padding: 1.25rem; }
  }

  /* ==================================================================
     KAG-specific additions: apps-list, settings-grid, JSON import row.
     ================================================================== */

  /* Layout picker: preset on the left, custom inline on the right.
     Flex-wrap means narrow viewports drop the custom inputs onto a
     second line gracefully - no media-query needed. Number inputs are
     constrained to 4ch so two of them fit alongside the preset on a
     mid-size screen. */
  .layout-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
  }
  .layout-row .layout-prompt,
  .layout-row .layout-or,
  .layout-row .layout-by {
    color: var(--muted);
    font-size: 0.9rem;
    white-space: nowrap;
  }
  /* Size the preset select to its content (widest option is "9 × 10",
     plus the chevron padding-right we added globally for selects). No
     min-width: the WAG-style hint copy below tells the user the cap. */
  .layout-row select { width: auto; }
  .layout-row input[type="number"] {
    width: 5rem;
    /* Strip browser spinner so the field reads as plain text input -
       the labels "cols"/"rows" carry the semantic. */
    appearance: textfield;
    -moz-appearance: textfield;
  }
  .layout-row input[type="number"]::-webkit-outer-spin-button,
  .layout-row input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }

  @media (max-width: 540px) {
    /* On phones the inline form would crowd; let the "or custom" half
       wrap to a new line and give the inputs more breathing room. */
    .layout-row .layout-or { width: 100%; margin-top: 0.25rem; }
    .layout-row input[type="number"] { flex: 1; max-width: 6rem; }
  }


  /* Dynamic apps list. Each row is package + row + col + label + remove. */
  .app-row {
    display: grid;
    grid-template-columns: 1fr 70px 70px 1fr 32px;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
    align-items: center;
  }
  /* Column headers above the apps list. Mirror the .app-row grid so
     the "Row" / "Col" labels sit directly over the dropdowns, making
     the link between the kiosk layout dimensions and these positional
     fields visible at a glance. Range hint (e.g. "(0–4)") is updated
     by syncLayout() in lockstep with preset / custom changes. */
  .apps-list-header {
    display: grid;
    grid-template-columns: 1fr 70px 70px 1fr 32px;
    gap: 0.5rem;
    margin-bottom: 0.35rem;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--muted);
  }
  .apps-list-header .range-hint {
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    color: var(--muted);
    opacity: 0.7;
    margin-left: 0.15rem;
  }
  .app-row input[type="text"],
  .app-row select {
    margin: 0;
  }
  .app-row.app-row-conflict input,
  .app-row.app-row-conflict select {
    border-color: #ff5252;
    box-shadow: 0 0 0 1px rgba(255, 82, 82, 0.4);
  }
  /* Amber flag when a layout shrink relocated this app's cell. Cleared
     the next time the user changes either row/col select on this row -
     they've acknowledged the new position. */
  .app-row.app-row-moved select {
    border-color: #f0a000;
    box-shadow: 0 0 0 1px rgba(240, 160, 0, 0.4);
  }
  .remove-row-btn {
    background: transparent;
    color: var(--muted);
    border: 1px solid var(--border);
    border-radius: 6px;
    width: 32px;
    height: 32px;
    cursor: pointer;
    font-size: 1.1rem;
    line-height: 1;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
  }
  .remove-row-btn:hover {
    color: #ff5252;
    border-color: #ff5252;
    background: rgba(255, 82, 82, 0.08);
  }
  .add-row-btn {
    background: transparent;
    color: var(--text);
    border: 1px dashed var(--border);
    border-radius: 8px;
    padding: 0.5rem 1rem;
    cursor: pointer;
    font-size: 0.9rem;
    width: 100%;
    margin-top: 0.25rem;
    transition: border-color 0.15s, background 0.15s;
  }
  .add-row-btn:hover {
    border-color: var(--primary);
    background: rgba(255, 69, 0, 0.05);
  }

  /* Folders editor. Each folder is a card containing a header row
     (name + col + row + remove) and a nested per-folder apps list
     with its own +Add button. Shares colour tokens and spacing with
     .app-row so the two sections feel coordinated. */
  .folder-card {
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 0.85rem 0.95rem 0.65rem;
    margin-bottom: 0.85rem;
    background: rgba(255, 255, 255, 0.02);
  }
  .folder-card.folder-card-conflict {
    border-color: #ff5252;
    box-shadow: 0 0 0 1px rgba(255, 82, 82, 0.4);
  }
  /* Column-header strip above the folder-card-header inputs.
     Mirrors the .apps-list-header pattern so operators see what each
     field is for. Grid template matches folder-card-header's columns
     1:1 so headers sit directly above their inputs. */
  .folder-card-grid-header {
    display: grid;
    grid-template-columns: 1fr 70px 70px 32px;
    gap: 0.5rem;
    margin-bottom: 0.35rem;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--muted);
  }
  .folder-card-header {
    display: grid;
    grid-template-columns: 1fr 70px 70px 32px;
    gap: 0.5rem;
    align-items: center;
    margin-bottom: 0.75rem;
  }
  .folder-card-header input[type="text"],
  .folder-card-header select {
    margin: 0;
  }
  /* "Folder background (optional)" label sits between the
     folder-card-header and the colour picker row. Styled to match
     the form's other field labels (uppercase, muted) so the section
     reads consistently. */
  .folder-bg-label {
    display: block;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 0.35rem;
  }
  /* The picker row itself inherits its layout from .colour-row (flex
     swatch + hidden native picker + text input); only need an extra
     hook here for the bottom margin within the folder card. */
  .folder-bg-row {
    margin-bottom: 0.55rem;
  }
  .folder-bg-color[disabled] {
    opacity: 0.45;
    cursor: not-allowed;
  }
  /* Folder app list (Package / Label rows + +Add button) sits at
     the same left edge as the folder name and background-colour
     fields above it. Earlier styling indented the apps list by
     0.65rem to suggest nesting, but the apps inside a folder are
     sibling fields at the same configuration level, not children
     of the folder name - so they align flush with the rest of
     the card. */
  .folder-apps-header {
    display: grid;
    grid-template-columns: 1fr 1fr 32px;
    gap: 0.5rem;
    margin-bottom: 0.35rem;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--muted);
  }
  .folder-app-row {
    display: grid;
    grid-template-columns: 1fr 1fr 32px;
    gap: 0.5rem;
    margin-bottom: 0.4rem;
    align-items: center;
  }
  .folder-app-row input[type="text"] {
    margin: 0;
  }
  .folder-add-app-btn {
    background: transparent;
    color: var(--text);
    border: 1px dashed var(--border);
    border-radius: 6px;
    padding: 0.35rem 0.75rem;
    cursor: pointer;
    font-size: 0.82rem;
    width: 100%;
    margin-top: 0.25rem;
    transition: border-color 0.15s, background 0.15s;
  }
  .folder-add-app-btn:hover:not(:disabled) {
    border-color: var(--primary);
    background: rgba(255, 69, 0, 0.05);
  }
  .folder-add-app-btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
  }
  .folder-app-count {
    font-weight: 400;
    color: var(--muted);
    margin-left: 0.4rem;
    font-size: 0.78rem;
  }

  @media (max-width: 540px) {
    .folder-card-header {
      grid-template-columns: 1fr;
    }
    /* Header strip drops when the folder card collapses to one
       column - the inputs' aria-label / placeholder is enough on
       narrow screens. */
    .folder-card-grid-header { display: none; }
    .folder-apps-header { display: none; }
    .folder-app-row {
      grid-template-columns: 1fr 1fr;
      grid-template-rows: auto auto;
    }
    .folder-app-row .remove-row-btn {
      grid-column: 1 / -1;
      justify-self: end;
    }
  }

  /* Settings-intents checkbox grid: 2-column on desktop, 1-column on mobile. */
  .checkbox-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.4rem 1rem;
    margin-top: 0.5rem;
  }
  .check-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.6rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.9rem;
    color: var(--text);
    user-select: none;
    transition: border-color 0.15s, background 0.15s;
  }
  .check-row:hover { border-color: var(--primary); }
  .check-row input { margin: 0; }

  @media (max-width: 540px) {
    .app-row { grid-template-columns: 1fr; }
    .checkbox-grid { grid-template-columns: 1fr; }
    /* Headers stack awkwardly when .app-row collapses to one column;
       the per-field labels are obvious enough in a single-col layout. */
    .apps-list-header { display: none; }
  }

  /* Code blocks in the in-page docs modal. Plain monospaced text
     on a surface2 panel, no syntax highlighting. Sized smaller than
     body text since these are illustrative snippets sitting inside
     longer prose paragraphs. Overflow scrolls horizontally so wide
     JSON examples don't break the modal layout on narrow viewports. */
  #docs-backdrop pre {
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.6rem 0.8rem;
    margin: 0.5rem 0;
    overflow-x: auto;
    font-size: 0.8rem;
    line-height: 1.5;
  }
  #docs-backdrop pre code {
    font-family: ui-monospace, 'Cascadia Code', 'Fira Mono', monospace;
    color: var(--text);
    background: none;
    padding: 0;
    white-space: pre;
  }

  /* Managed Settings opt-in card. Sits above the per-panel toggle
     rows in the Settings Menu Access field. Visually distinct from
     the .sign-option cards (which look clickable as a radio):
     non-clickable flat grey-toned surface with rounded corners, a
     toggle row at the top, and explanatory hints underneath. Two
     hints because the message is two-part: what the toggle does, and
     the deployment caveat. */
  .managed-settings-card {
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.6rem 0.9rem;
    /* Symmetric vertical breathing room. margin-top mirrors
       margin-bottom so the visual gap above the card (to the
       section's intro .hint) matches the gap below (to the first
       per-panel toggle row). */
    margin-top: 0.85rem;
    margin-bottom: 0.85rem;
  }
  .managed-settings-card .toggle-row {
    padding: 0;
  }
  .managed-settings-card .hint {
    margin-top: 0.4rem;
    margin-bottom: 0;
  }
  .managed-settings-card .hint + .hint {
    margin-top: 0.4rem;
  }

  /* Two-column reference table used in the in-page docs (e.g. the
     folder-key JSON-vs-EMM mapping in the Folders section). Plain
     borders, surface2 header strip, no per-row striping; sits in
     the existing dark surface without competing with form controls. */
  table.key-mapping {
    border-collapse: collapse;
    margin: 0.6rem 0;
    width: 100%;
    font-size: 0.9rem;
  }
  table.key-mapping th,
  table.key-mapping td {
    border: 1px solid var(--border);
    padding: 0.4rem 0.6rem;
    text-align: left;
    vertical-align: top;
  }
  table.key-mapping th {
    background: var(--surface2);
    font-weight: 600;
  }
