/**
 * Apple Human Interface Guidelines — implemented to specification
 * ===============================================================
 *
 * Everything below is Apple's published values, not an approximation of the
 * look. Where a number appears it comes from one of:
 *
 *   - HIG > Color > System colors and semantic colors (exact sRGB)
 *   - HIG > Typography > iOS Dynamic Type sizes (size / leading / tracking)
 *   - HIG > Layout (8pt grid, 44pt minimum hit target, standard margins)
 *   - HIG > Materials (blur levels, vibrancy)
 *
 * WHY THE iOS SCALE AND NOT THE macOS ONE
 * ---------------------------------------
 * Apple publishes two type scales. macOS is denser (13pt body); iOS is larger
 * (17pt body). This app is served in a browser and the extension popup is
 * 380pt wide -- narrower than an iPhone 15's 393pt -- so iOS metrics are
 * literally the correct spec for that surface, and 17pt body renders properly
 * on the web where 13pt would be uncomfortably small. One scale is used
 * everywhere rather than mixing the two.
 *
 * THE 8-POINT GRID
 * ----------------
 * Every margin, padding and gap is a multiple of 4, and preferentially of 8.
 * Standard content margin is 16pt. Nothing is eyeballed.
 *
 * CONCENTRICITY
 * -------------
 * inner_radius = outer_radius − padding. Radii below are derived from that
 * relation, not chosen: 20 − 4 = 16, 16 − 6 = 10, 10 − 4 = 6.
 */

/* ========================================================================== */
/* Apple system colors — HIG > Color                                          */
/* ========================================================================== */

:root {
  /* --- system colors, light ---------------------------------------------- */
  --red:      #FF3B30;
  --orange:   #FF9500;
  --yellow:   #FFCC00;
  --green:    #34C759;
  --mint:     #00C7BE;
  --teal:     #30B0C7;
  --cyan:     #32ADE6;
  --blue:     #007AFF;
  --indigo:   #5856D6;
  --purple:   #AF52DE;
  --pink:     #FF2D55;
  --brown:    #A2845E;

  /* --- gray scale, light -------------------------------------------------- */
  --gray:     #8E8E93;
  --gray2:    #AEAEB2;
  --gray3:    #C7C7CC;
  --gray4:    #D1D1D6;
  --gray5:    #E5E5EA;
  --gray6:    #F2F2F7;

  /* --- label colors, light ------------------------------------------------
     Apple specifies these as translucent so they compose over any backdrop.
     Alpha, not a lighter grey -- that is the whole point of the spec. */
  --label:            rgba(0, 0, 0, 1);
  --label-secondary:  rgba(60, 60, 67, 0.60);
  --label-tertiary:   rgba(60, 60, 67, 0.30);
  --label-quaternary: rgba(60, 60, 67, 0.18);

  /* --- fill colors, light — for shapes behind content --------------------- */
  --fill:            rgba(120, 120, 128, 0.20);
  --fill-secondary:  rgba(120, 120, 128, 0.16);
  --fill-tertiary:   rgba(118, 118, 128, 0.12);
  --fill-quaternary: rgba(116, 116, 128, 0.08);

  /* --- backgrounds, light ------------------------------------------------- */
  --bg:             #FFFFFF;
  --bg-secondary:   #F2F2F7;
  --bg-tertiary:    #FFFFFF;
  --bg-grouped:           #F2F2F7;
  --bg-grouped-secondary: #FFFFFF;
  --bg-grouped-tertiary:  #F2F2F7;

  /* --- separators, light -------------------------------------------------- */
  --separator:        rgba(60, 60, 67, 0.29);
  --separator-opaque: #C6C6C8;

  /* --- tint --------------------------------------------------------------- */
  --tint:       var(--blue);
  --tint-press: #0062CC;
  --tint-soft:  rgba(0, 122, 255, 0.12);

  /* --- materials — HIG > Materials ---------------------------------------
     Apple's blur levels, approximated with the closest CSS equivalents.
     Saturation is what stops a blurred backdrop turning grey. */
  /* Liquid Glass is thinner and blurrier than the pre-26 materials: more of
     the backdrop comes through, and it is bent rather than merely frosted. */
  --mat-ultrathin: rgba(255, 255, 255, 0.30);
  --mat-thin:      rgba(255, 255, 255, 0.42);
  --mat-regular:   rgba(255, 255, 255, 0.55);
  --mat-thick:     rgba(255, 255, 255, 0.70);
  --blur-regular:  32px;
  --blur-thick:    56px;
  --sat:           200%;

  /* Liquid Glass rim. Bright along the top where light lands, faint beneath —
     this is what reads as thickness rather than as a flat tinted panel. */
  --rim-top:   rgba(255, 255, 255, 0.90);
  --rim-under: rgba(255, 255, 255, 0.28);
  --rim-hair:  rgba(255, 255, 255, 0.50);
  --rim-edge:  rgba(0, 0, 0, 0.06);

  /* --- shadows ------------------------------------------------------------
     Apple does NOT use drop shadows to separate surfaces. Cards, list rows,
     buttons and chips have none: an inset grouped list is
     secondarySystemGroupedBackground sitting on systemGroupedBackground, and
     the *background step* is the separation. Adding elevation shadows there is
     Material Design thinking, not Apple's.
     There are exactly two places a shadow is legitimate:
       - a sheet/popover floating over a dimmed backdrop (the window server
         draws this on macOS; on the web we draw it ourselves)
       - a physical knob lifted off its track (switch, slider)
     Nothing else gets one. */
  --shadow-sheet: 0 24px 68px rgba(0, 0, 0, 0.22), 0 4px 12px rgba(0, 0, 0, 0.08);
  --shadow-knob:  0 3px 8px rgba(0, 0, 0, 0.15), 0 1px 1px rgba(0, 0, 0, 0.16);

  /* --- 8-point grid — HIG > Layout ---------------------------------------- */
  --sp-1:  4px;
  --sp-2:  8px;
  --sp-3:  12px;
  --sp-4:  16px;   /* standard content margin */
  --sp-5:  20px;
  --sp-6:  24px;
  --sp-8:  32px;
  --sp-10: 40px;
  --sp-12: 48px;

  /* --- Liquid Glass geometry ----------------------------------------------
     `.glassEffect()` defaults to `.capsule`, so controls are capsules unless
     there is a reason not to be. Container radii are then SOLVED from that,
     not picked, following containerConcentric:

         outer = inner + gap

     sidebar : nav rows are capsules on a 40px row, so inner = 20.
               gap is 8, therefore sidebar = 28.
     card    : list rows sit in 4px of padding, so card = row + 4 = 24.
     row     : 20, which keeps it a rounded rect rather than a capsule at the
               56px row height, so long names still read as a line of text.

     Deep nesting (a 16px field inside a modal's 24px body padding) is exempt:
     concentricity is only perceptible when the corners are close together. */
  --r-window:  28px;
  --r-card:    24px;
  --r-row:     20px;
  --r-field:   16px;
  --r-inner:   12px;
  --r-control: 999px;  /* capsule, the default Liquid Glass shape */
  --r-pill:    999px;

  /* --- minimum hit target — HIG > Layout ---------------------------------- */
  --target: 44px;

  /* --- motion -------------------------------------------------------------
     Apple's standard interface spring. The long tail is what gives a surface
     apparent mass; a linear ease reads as a slide, not a push. */
  --ease:      cubic-bezier(0.32, 0.72, 0, 1);
  --ease-out:  cubic-bezier(0.16, 1, 0.3, 1);
  --dur:       0.4s;
  --dur-fast:  0.2s;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* Apple ships *different* hues for dark mode, brighter and less saturated,
       so they hold contrast on black. Reusing the light values is the single
       most common way a dark theme ends up looking muddy. */
    --red:      #FF453A;
    --orange:   #FF9F0A;
    --yellow:   #FFD60A;
    --green:    #30D158;
    --mint:     #63E6E2;
    --teal:     #40C8E0;
    --cyan:     #64D2FF;
    --blue:     #0A84FF;
    --indigo:   #5E5CE6;
    --purple:   #BF5AF2;
    --pink:     #FF375F;
    --brown:    #AC8E68;

    --gray:     #8E8E93;
    --gray2:    #636366;
    --gray3:    #48484A;
    --gray4:    #3A3A3C;
    --gray5:    #2C2C2E;
    --gray6:    #1C1C1E;

    --label:            rgba(255, 255, 255, 1);
    --label-secondary:  rgba(235, 235, 245, 0.60);
    --label-tertiary:   rgba(235, 235, 245, 0.30);
    --label-quaternary: rgba(235, 235, 245, 0.16);

    --fill:            rgba(120, 120, 128, 0.36);
    --fill-secondary:  rgba(120, 120, 128, 0.32);
    --fill-tertiary:   rgba(118, 118, 128, 0.24);
    --fill-quaternary: rgba(118, 118, 128, 0.18);

    --bg:             #000000;
    --bg-secondary:   #1C1C1E;
    --bg-tertiary:    #2C2C2E;
    --bg-grouped:           #000000;
    --bg-grouped-secondary: #1C1C1E;
    --bg-grouped-tertiary:  #2C2C2E;

    --separator:        rgba(84, 84, 88, 0.65);
    --separator-opaque: #38383A;

    --tint:       var(--blue);
    --tint-press: #0071E3;
    --tint-soft:  rgba(10, 132, 255, 0.18);

    --mat-ultrathin: rgba(28, 28, 30, 0.36);
    --mat-thin:      rgba(28, 28, 30, 0.50);
    --mat-regular:   rgba(28, 28, 30, 0.62);
    --mat-thick:     rgba(28, 28, 30, 0.76);

    /* On black the rim is the only thing separating one glass surface from
       another, so it carries more of the load, not less. */
    --rim-top:   rgba(255, 255, 255, 0.20);
    --rim-under: rgba(255, 255, 255, 0.04);
    --rim-hair:  rgba(255, 255, 255, 0.10);
    --rim-edge:  rgba(0, 0, 0, 0.50);

    --shadow-sheet: 0 24px 68px rgba(0, 0, 0, 0.68), 0 4px 12px rgba(0, 0, 0, 0.40);
    --shadow-knob:  0 3px 8px rgba(0, 0, 0, 0.40), 0 1px 1px rgba(0, 0, 0, 0.30);
  }
}

/* ========================================================================== */
/* reset                                                                      */
/* ========================================================================== */

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

html { -webkit-text-size-adjust: 100%; }

/**
 * The system font stack. On macOS and iOS `-apple-system` resolves to SF Pro,
 * which is the actual typeface the HIG specifies -- no webfont needed, and no
 * licensing question.
 *
 * `font-optical-sizing: auto` is what switches SF Pro Text to SF Pro Display
 * above 20pt, exactly as Apple's own platforms do. Without it, large headings
 * keep Text's looser spacing and look subtly wrong.
 */
body {
  margin: 0;
  min-height: 100vh;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display",
               system-ui, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  font-optical-sizing: auto;
  font-synthesis-weight: none;
  color: var(--label);
  background: var(--bg-grouped);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;

  /* Body — 17 / 22, tracking −0.43pt */
  font-size: 17px;
  line-height: 22px;
  letter-spacing: -0.0253em;
}

button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
button { -webkit-tap-highlight-color: transparent; }
svg { flex: 0 0 auto; display: block; }

/* ========================================================================== */
/* Typography — HIG > Typography, iOS Dynamic Type (Large)                    */
/*                                                                            */
/* size / leading / tracking, exactly as published. Tracking is converted from */
/* Apple's points to em by dividing by the size, so it scales correctly.      */
/* ========================================================================== */

.large-title { font-size: 34px; line-height: 41px; letter-spacing:  0.0109em; font-weight: 400; }
.title-1     { font-size: 28px; line-height: 34px; letter-spacing:  0.0129em; font-weight: 400; }
.title-2     { font-size: 22px; line-height: 28px; letter-spacing:  0.0159em; font-weight: 400; }
.title-3     { font-size: 20px; line-height: 25px; letter-spacing:  0.0190em; font-weight: 400; }
.headline    { font-size: 17px; line-height: 22px; letter-spacing: -0.0253em; font-weight: 600; }
.body        { font-size: 17px; line-height: 22px; letter-spacing: -0.0253em; font-weight: 400; }
.callout     { font-size: 16px; line-height: 21px; letter-spacing: -0.0194em; font-weight: 400; }
.subheadline { font-size: 15px; line-height: 20px; letter-spacing: -0.0153em; font-weight: 400; }
.footnote    { font-size: 13px; line-height: 18px; letter-spacing: -0.0062em; font-weight: 400; }
.caption-1   { font-size: 12px; line-height: 16px; letter-spacing:  0;        font-weight: 400; }
.caption-2   { font-size: 11px; line-height: 13px; letter-spacing:  0.0055em; font-weight: 400; }

/* Headings map onto the scale rather than inventing their own sizes. */
h1 { font-size: 28px; line-height: 34px; letter-spacing: 0.0129em; font-weight: 700; margin: 0; }
h2 { font-size: 22px; line-height: 28px; letter-spacing: 0.0159em; font-weight: 700; margin: 0; }
h3 { font-size: 17px; line-height: 22px; letter-spacing: -0.0253em; font-weight: 600; margin: 0; }

.secondary  { color: var(--label-secondary); }
.tertiary   { color: var(--label-tertiary); }

/* Apple's grouped-list section header: footnote, uppercase, secondary label. */
.section-header {
  font-size: 13px;
  line-height: 18px;
  letter-spacing: 0.06em;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--label-secondary);
}

.mono {
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;
  letter-spacing: 0;
  font-variant-ligatures: none;
}

/* Tabular figures stop counters and timestamps jittering as they update. */
.tnum { font-variant-numeric: tabular-nums; }

/* ========================================================================== */
/* Backdrop                                                                   */
/*                                                                            */
/* Glass needs something worth refracting. Colour sits at the edges, where     */
/* panels overlap it; the reading area stays close to the system background,   */
/* which is what Apple does and what keeps text legible.                       */
/* ========================================================================== */

body::before {
  content: '';
  position: fixed;
  inset: -20%;
  z-index: -2;
  background:
    radial-gradient(34% 38% at 0% 0%,    rgba(0, 122, 255, 0.42), transparent 72%),
    radial-gradient(32% 34% at 100% 2%,  rgba(175, 82, 222, 0.36), transparent 72%),
    radial-gradient(36% 38% at 100% 100%, rgba(52, 199, 89, 0.28), transparent 72%),
    radial-gradient(34% 36% at 0% 100%,  rgba(255, 149, 0, 0.30),  transparent 72%),
    var(--bg-grouped);
  filter: blur(40px);
  animation: drift 40s var(--ease) infinite alternate;
}

@media (prefers-color-scheme: dark) {
  body::before {
    background:
      radial-gradient(34% 38% at 0% 0%,     rgba(10, 132, 255, 0.34), transparent 72%),
      radial-gradient(32% 34% at 100% 2%,   rgba(191, 90, 242, 0.28), transparent 72%),
      radial-gradient(36% 38% at 100% 100%, rgba(48, 209, 88, 0.20),  transparent 72%),
      radial-gradient(34% 36% at 0% 100%,   rgba(255, 159, 10, 0.20), transparent 72%),
      #000000;
    filter: blur(44px);
  }
}

/* Fine luminance grain. Without it, wide gradients band visibly on 8-bit
   displays -- the same reason Apple dithers its own wallpapers. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.020;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

@keyframes drift {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(-2%, 1.6%, 0) scale(1.05); }
  100% { transform: translate3d(1.6%, -2%, 0) scale(1.02); }
}

/* ========================================================================== */
/* Materials — HIG > Materials                                                */
/* ========================================================================== */

.material {
  position: relative;
  background: var(--mat-regular);
  backdrop-filter: blur(var(--blur-regular)) saturate(var(--sat));
  -webkit-backdrop-filter: blur(var(--blur-regular)) saturate(var(--sat));
  border-radius: var(--r-card);
  /* No hairline border and no heavy ring: Liquid Glass is defined by its rim
     highlight and its shadow, not by an outline. */
  /* Rim only. Liquid Glass separates itself by lensing and its highlight;
     a drop shadow underneath it is the giveaway of an imitation. */
  box-shadow:
    inset 0 1px 1px 0 var(--rim-top),
    inset 0 -1px 1px 0 var(--rim-under);
  isolation: isolate;
}

/**
 * LENSING — the part that separates Liquid Glass from frosted glass.
 *
 * A ring hugging the inside of the edge gets its *own* backdrop-filter, more
 * aggressive than the panel's, masked so it only paints in the outer few
 * pixels. Content passing behind the boundary is therefore distorted
 * differently from content behind the middle, which is exactly what a real
 * lens does and what a single flat blur cannot fake.
 */
.material::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 0;
  backdrop-filter: blur(2px) brightness(1.16) saturate(1.5);
  -webkit-backdrop-filter: blur(2px) brightness(1.16) saturate(1.5);
  /* Paint only the rim: transparent in the middle, opaque at the edge. */
  /**
   * The ring is carved with a transparent BORDER, not padding.
   *
   * `border-radius` automatically reduces the radius of the padding box by the
   * border width, so both edges of the ring come out correctly rounded. The
   * content-box version of this trick leaves the inner edge square-cornered,
   * which shows up as a hard bright band across the top of every panel.
   */
  border: 5px solid transparent;
  -webkit-mask:
    linear-gradient(#000 0 0) padding-box,
    linear-gradient(#000 0 0);
  mask:
    linear-gradient(#000 0 0) padding-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
}

@media (prefers-color-scheme: dark) {
  .material::after { backdrop-filter: blur(2px) brightness(1.5) saturate(1.4); -webkit-backdrop-filter: blur(2px) brightness(1.5) saturate(1.4); }
}

/**
 * The specular highlight — a bright arc across the top-left, fading out.
 *
 * On iOS 26 this shifts with device motion. On the web there is no gyroscope
 * to drive it, so it is fixed to a consistent light direction rather than
 * faked with an animation that would just look restless.
 */
.material::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 1;
  background:
    linear-gradient(145deg,
      rgba(255, 255, 255, 0.55) 0%,
      rgba(255, 255, 255, 0.14) 22%,
      transparent 46%),
    radial-gradient(120% 90% at 12% 0%,
      rgba(255, 255, 255, 0.40) 0%,
      transparent 55%);
}

@media (prefers-color-scheme: dark) {
  .material::before {
    background:
      linear-gradient(145deg,
        rgba(255, 255, 255, 0.16) 0%,
        rgba(255, 255, 255, 0.04) 24%,
        transparent 48%),
      radial-gradient(120% 90% at 12% 0%,
        rgba(255, 255, 255, 0.12) 0%,
        transparent 55%);
  }
}

.material > * { position: relative; z-index: 2; }

.material-thick { background: var(--mat-thick); backdrop-filter: blur(var(--blur-thick)) saturate(var(--sat)); -webkit-backdrop-filter: blur(var(--blur-thick)) saturate(var(--sat)); }
.material-thin  { background: var(--mat-thin);  backdrop-filter: blur(14px) saturate(160%); -webkit-backdrop-filter: blur(14px) saturate(160%); }

/* Apple's corners are continuous curvature, not circular arcs — the curve
   eases into the straight edge so there is no visible seam. */
@supports (corner-shape: squircle) {
  .material, .card, .btn, .row-item, .modal, .sidebar, input, select, textarea { corner-shape: squircle; }
}

/* HIG: honour Reduce Transparency and Reduce Motion. Translucency is
   decoration; legibility is not. */
@media (prefers-reduced-transparency: reduce) {
  .material, .material-thick, .material-thin {
    background: var(--bg-grouped-secondary);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  body::before { opacity: 0.15; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ========================================================================== */
/* Layout                                                                     */
/* ========================================================================== */

.shell {
  display: grid;
  grid-template-columns: 284px minmax(0, 1fr);
  gap: var(--sp-3);
  padding: var(--sp-3);
  min-height: 100vh;
  align-items: start;
}

.sidebar {
  position: sticky;
  top: var(--sp-3);
  height: calc(100vh - var(--sp-6));
  padding: var(--sp-4) var(--sp-2) var(--sp-2);
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
  overscroll-behavior: contain;
  border-radius: var(--r-window);
}

.content { min-width: 0; padding: var(--sp-2) var(--sp-2) var(--sp-12); }

.brand { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-1) var(--sp-2) var(--sp-5); }
.brand img { width: 36px; height: 36px; border-radius: 9px; flex: 0 0 auto; }
.brand .text { min-width: 0; }
.brand .name {
  display: block;
  font-size: 17px; line-height: 22px; letter-spacing: -0.0253em; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brand .org {
  display: block;
  font-size: 13px; line-height: 18px; letter-spacing: -0.0062em;
  color: var(--label-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ========================================================================== */
/* Sidebar navigation                                                         */
/* ========================================================================== */

.nav {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  min-height: 40px;              /* pointer-density row; ≥44 for touch below */
  padding: var(--sp-2) var(--sp-4);
  border: 0;
  border-radius: var(--r-control);   /* capsule, as iOS 26 sidebar rows are */
  background: transparent;
  text-align: left;
  cursor: pointer;
  color: var(--label);
  font-size: 15px; line-height: 20px; letter-spacing: -0.0153em; font-weight: 400;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.nav:hover { background: var(--fill-quaternary); }
.nav:active { background: var(--fill-tertiary); }

.nav.on {
  background: var(--tint-soft);
  color: var(--tint);
  font-weight: 600;
  box-shadow: inset 0 1px 1px 0 rgba(255, 255, 255, 0.45);
}

.nav .ico { flex: 0 0 22px; height: 22px; display: grid; place-items: center; color: var(--label-secondary); transition: color var(--dur-fast) var(--ease); }
.nav.on .ico { color: var(--tint); }

.nav .txt { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.nav .count {
  flex: 0 0 auto;
  font-size: 13px; line-height: 18px;
  font-variant-numeric: tabular-nums;
  color: var(--label-secondary);
  padding: 0 var(--sp-2);
  border-radius: var(--r-pill);
  background: var(--fill-quaternary);
}
.nav.on .count { background: rgba(0, 122, 255, 0.16); color: var(--tint); }

.nav-group { padding: var(--sp-5) var(--sp-3) var(--sp-1); }
.sidebar-foot { margin-top: auto; padding-top: var(--sp-2); }

/* Touch pointers get Apple's 44pt minimum; a mouse does not need it, and
   forcing 44pt everywhere on desktop wastes a lot of vertical space. */
@media (pointer: coarse) {
  .nav { min-height: var(--target); }
}

/* ========================================================================== */
/* Cards — Apple's inset grouped list                                         */
/* ========================================================================== */

/**
 * Content cards are OPAQUE, not glass.
 *
 * Apple applies Liquid Glass to the control layer -- bars, sidebars, buttons --
 * and leaves the content layer solid. Glass on content competes with the text
 * it holds, and Apple's own guidance says not to.
 *
 * Separation is the background step (secondarySystemGroupedBackground over
 * systemGroupedBackground), never a shadow.
 */
.card {
  border-radius: var(--r-card);
  margin-bottom: var(--sp-4);
  overflow: hidden;
  background: var(--bg-grouped-secondary);
}
/* A card carrying .material would get glass; content cards must not. */
.card.material { background: var(--bg-grouped-secondary); backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none; }
.card.material::before, .card.material::after { display: none; }

/* No hairline under the header: Liquid Glass separates by depth and spacing,
   not by drawn rules. */
.card > header { padding: var(--sp-5) var(--sp-5) var(--sp-2); }
.card > header .sub {
  color: var(--label-secondary);
  font-size: 13px; line-height: 18px; letter-spacing: -0.0062em;
  margin-top: var(--sp-1);
}
.card .body { padding: var(--sp-2) var(--sp-5) var(--sp-5); }

/* ========================================================================== */
/* Toolbar and search                                                         */
/* ========================================================================== */

.toolbar { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-4); flex-wrap: wrap; }
.toolbar .grow { flex: 1 1 260px; min-width: 0; }

.search { position: relative; display: flex; align-items: center; }
.search .ico { position: absolute; left: var(--sp-3); color: var(--label-tertiary); pointer-events: none; }

/**
 * Apple's search field: capsule, filled, no border.
 *
 * Selector is deliberately more specific than the generic `input[type=text]`
 * block below. At equal specificity the later rule wins and silently resets
 * this padding, which puts the magnifier on top of the placeholder.
 */
.search input[type=text] {
  width: 100%;
  height: 36px;
  padding: 0 var(--sp-4) 0 var(--sp-10);   /* clears the 12px+16px magnifier */
  border: 0;
  border-radius: var(--r-pill);
  background: var(--fill-tertiary);
  font-size: 17px; line-height: 22px; letter-spacing: -0.0253em;
  transition: box-shadow var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.search input::placeholder { color: var(--label-tertiary); }

/* ==========================================================================
   Focus
   ==========================================================================

   Apple does not ring a control because you clicked it. Tap a text field on
   iOS and you get a caret -- nothing else. The heavy halo-on-click is a web
   convention, not an Apple one, so `:focus` carries no styling here.

   Keyboard focus is a different question, and it is NOT dropped. macOS Full
   Keyboard Access draws a real accent ring, and removing it would lock out
   anyone navigating by Tab. `:focus-visible` fires only for keyboard
   interaction, so the ring appears exactly where Apple puts it and never on a
   mouse click.
   ========================================================================== */

:focus { outline: none; }

:focus-visible {
  outline: 2px solid var(--tint);   /* Chrome rounds sub-pixel outlines anyway */
  /* The gap is what makes macOS focus read as a ring rather than a border.
     `outline` already follows the element's own border-radius, so the shape
     needs no help -- and setting border-radius here would overwrite it. */
  outline-offset: 2px;
}

/**
 * Text fields are exempt.
 *
 * Per spec a text input matches `:focus-visible` whenever it is focused --
 * including a mouse click -- because it accepts keyboard input. That would put
 * a ring on every field the moment you click it, which is the exact web
 * convention we are removing.
 *
 * Suppressing it costs nothing in accessibility: a focused text field shows a
 * blinking caret in every modality, so focus stays visible without a ring.
 * This is what iOS does.
 */
input[type=text]:focus-visible,
input[type=password]:focus-visible,
input[type=email]:focus-visible,
input[type=url]:focus-visible,
input[type=number]:focus-visible,
input[type=date]:focus-visible,
input[type=search]:focus-visible,
textarea:focus-visible {
  outline: none;
}

/* ========================================================================== */
/* Buttons — HIG > Buttons                                                    */
/* ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 40px;
  padding: var(--sp-2) var(--sp-5);
  border: 0;
  border-radius: var(--r-control);      /* capsule */
  background: var(--fill-quaternary);
  color: var(--tint);
  font-size: 17px; line-height: 22px; letter-spacing: -0.0253em; font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;   /* the button styling also serves <a download> */
  transition: transform var(--dur-fast) var(--ease),
              background var(--dur-fast) var(--ease),
              filter var(--dur-fast) var(--ease);
}

/* Numbered install steps (extension card). */
.steps {
  margin: 0;
  padding-left: 1.35em;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  color: var(--label-secondary);
  font-size: 15px;
  line-height: 20px;
}
.steps li { padding-left: 0.15em; }

.btn:hover { background: var(--fill-tertiary); }

/* The press. Scale reads as the surface being pushed toward the page; an
   opacity fade never feels physical. */
.btn:active { transform: scale(0.96); background: var(--fill-secondary); }
.btn:disabled { opacity: 0.35; cursor: default; transform: none; }

/**
 * Prominent button — tinted Liquid Glass.
 *
 * Pre-26 this was a flat opaque fill. In iOS 26 a prominent glass button is
 * the material *tinted*, so the backdrop still shows through and the rim
 * highlight still reads. Hence the rim inset shadows on a coloured base.
 */
.btn-filled {
  background: var(--tint);
  color: #FFFFFF;
  /* Rim highlight only -- no glow, no drop shadow. */
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.40),
    inset 0 -1px 1px rgba(0, 0, 0, 0.08);
}
.btn-filled:hover { filter: brightness(1.06) saturate(1.06); }
.btn-filled:active { background: var(--tint-press); filter: none; }

.btn-gray { background: var(--fill-tertiary); color: var(--label); }
.btn-destructive { background: var(--red); color: #FFFFFF; }
.btn-destructive:active { background: var(--red); filter: brightness(0.9); }
.btn-plain { background: transparent; }
.btn-plain:hover { background: var(--fill-quaternary); }
.btn-danger-plain { background: transparent; color: var(--red); }
.btn-danger-plain:hover { background: rgba(255, 59, 48, 0.10); }

.btn-block { width: 100%; }
.btn-small { min-height: 32px; padding: var(--sp-1) var(--sp-4); font-size: 15px; line-height: 20px; letter-spacing: -0.0153em; }

@media (pointer: coarse) { .btn { min-height: var(--target); } }

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: 50%;                   /* capsule at 1:1 is a circle */
  background: transparent;
  color: var(--label-secondary);
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              background var(--dur-fast) var(--ease);
}
.icon-btn:hover { color: var(--label); background: var(--fill-quaternary); }
.icon-btn:active { transform: scale(0.90); background: var(--fill-tertiary); }

@media (pointer: coarse) { .icon-btn { width: var(--target); height: var(--target); } }

/* ========================================================================== */
/* Text fields                                                                */
/* ========================================================================== */

.field { display: block; margin-bottom: var(--sp-4); }
.field > .label { display: block; margin-bottom: var(--sp-2); }
.field .hint {
  display: block;
  margin-top: var(--sp-2);
  color: var(--label-secondary);
  font-size: 13px; line-height: 18px; letter-spacing: -0.0062em;
}

.label {
  font-size: 13px; line-height: 18px;
  letter-spacing: 0.06em;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--label-secondary);
}

input[type=text], input[type=password], input[type=email], input[type=url],
input[type=number], input[type=date], select, textarea {
  width: 100%;
  min-height: 40px;
  padding: var(--sp-2) var(--sp-4);
  border: 0;
  /* A capsule text field is only right for search. Multi-field forms use the
     rounded rectangle, or long values crowd the curve. */
  border-radius: var(--r-field);
  background: var(--fill-tertiary);
  color: var(--label);
  font-size: 17px; line-height: 22px; letter-spacing: -0.0253em;
  transition: box-shadow var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

input::placeholder, textarea::placeholder { color: var(--label-tertiary); }

/* Focused and unfocused look identical, as they do on iOS -- the caret is the
   indicator. Handled by the global `:focus` rule; a per-element rule here
   would out-specify `:focus-visible` and silently remove the keyboard ring. */

textarea {
  border-radius: var(--r-field);
  min-height: 88px;
  resize: vertical;
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;
  font-size: 15px; line-height: 20px; letter-spacing: 0;
}

select {
  appearance: none;
  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 d='M1 1.5 6 6.5l5-5' stroke='%238E8E93' stroke-width='1.8' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--sp-3) center;
  padding-right: var(--sp-8);
}

.row { display: flex; gap: var(--sp-2); align-items: center; }
.row > * { flex: 1 1 0; min-width: 0; }
.row > .fit { flex: 0 0 auto; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--sp-4); }

/* --- Checkbox — drawn, so it inherits the tint and scales cleanly --------- */

input[type=checkbox] {
  appearance: none;
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  min-height: 0;
  padding: 0;
  border-radius: 50%;                   /* iOS 26 checkmarks are circular */
  background: var(--fill-tertiary);
  cursor: pointer;
  position: relative;
  transition: background var(--dur-fast) var(--ease);
}
input[type=checkbox]:checked { background: var(--tint); }
input[type=checkbox]:checked::after {
  content: '';
  position: absolute;
  left: 8.5px; top: 4.5px;
  width: 6px; height: 11px;
  border: solid #FFFFFF;
  border-width: 0 2px 2px 0;
  transform: rotate(43deg);
}

/* --- Switch — Apple's exact geometry: 51 × 31, 27pt knob, 2pt inset ------- */

.switch { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-3) 0; cursor: pointer; min-height: var(--target); }
.switch + .switch { box-shadow: inset 0 0.5px 0 var(--separator); }
.switch .txt { flex: 1; }
.switch .txt b { display: block; font-size: 17px; line-height: 22px; letter-spacing: -0.0253em; font-weight: 400; }
.switch .txt span {
  display: block;
  color: var(--label-secondary);
  font-size: 13px; line-height: 18px; letter-spacing: -0.0062em;
  margin-top: 2px;
}
.switch input { position: absolute; opacity: 0; pointer-events: none; }

.switch .track {
  flex: 0 0 auto;
  position: relative;
  width: 51px;
  height: 31px;
  border-radius: var(--r-pill);
  background: var(--fill);
  transition: background var(--dur) var(--ease);
}
.switch .track::after {
  content: '';
  position: absolute;
  top: 2px; left: 2px;
  width: 27px; height: 27px;
  border-radius: 50%;
  background: #FFFFFF;
  box-shadow: var(--shadow-knob);   /* a knob lifted off its track */
  transition: transform var(--dur) var(--ease), width var(--dur) var(--ease);
}
.switch input:checked + .track { background: var(--green); }
.switch input:checked + .track::after { transform: translateX(20px); }
/* The knob stretches under the thumb before settling — the spring is the tell. */
.switch:active .track::after { width: 31px; }
.switch input:checked + .track:active::after { transform: translateX(16px); }

/* --- Segmented control --------------------------------------------------- */

.segmented {
  display: flex;
  gap: 2px;
  padding: 3px;
  border-radius: var(--r-control);
  background: var(--fill-tertiary);
}
.segmented button {
  flex: 1 1 0;
  min-height: 30px;
  padding: 0 var(--sp-3);
  border: 0;
  border-radius: var(--r-control);
  background: transparent;
  color: var(--label);
  font-size: 15px; line-height: 20px; letter-spacing: -0.0153em; font-weight: 500;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
/* The selected segment is a raised knob -- Apple gives this one a shadow
   because it is a physical control, like a switch knob. */
.segmented button.on {
  background: var(--bg-grouped-secondary);
  font-weight: 600;
  box-shadow: var(--shadow-knob);
}

/* ========================================================================== */
/* List rows — Apple's grouped list                                           */
/* ========================================================================== */

.list { padding: var(--sp-1); }

.item-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  min-height: 56px;               /* ≥44pt target, with Liquid Glass breathing room */
  padding: var(--sp-2) var(--sp-3);
  border: 0;
  border-radius: var(--r-row);    /* card 24 minus the list's 4px padding */
  background: transparent;
  text-align: left;
  cursor: pointer;
  color: var(--label);
  transition: background var(--dur-fast) var(--ease);
}
.item-row:hover { background: var(--fill-quaternary); }
.item-row:active { background: var(--fill-tertiary); }

.item-row .avatar {
  flex: 0 0 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: var(--r-inner);
  background: var(--fill-quaternary);
  color: var(--label-secondary);
}

/* Tint each item type with a system color — a fast visual index, so you stop
   reading subtitles to tell a database from an FTP box. */
.avatar[data-type="1"] { color: var(--blue); }
.avatar[data-type="2"] { color: var(--orange); }
.avatar[data-type="3"] { color: var(--green); }
.avatar[data-type="4"] { color: var(--indigo); }
.avatar[data-type="5"] { color: var(--pink); }
.avatar[data-type="6"] { color: var(--gray); }
.avatar[data-type="7"] { color: var(--purple); }

/* Two stacked lines, not two inline spans — otherwise title and subtitle
   collide on one line. */
.item-row .text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.item-row .name {
  display: block;
  font-size: 17px; line-height: 22px; letter-spacing: -0.0253em; font-weight: 400;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.item-row .sub {
  display: block;
  font-size: 13px; line-height: 18px; letter-spacing: -0.0062em;
  color: var(--label-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/**
 * Quick actions overlay the row rather than sitting in the flex flow.
 *
 * `opacity: 0` hides them but still reserves their width, which silently
 * truncates item names that would otherwise fit. Absolute positioning returns
 * that space to the title.
 */
.item-row { position: relative; }
.item-row .quick {
  position: absolute;
  right: var(--sp-3);
  top: 50%;
  transform: translateY(-50%) translateX(6px);
  display: flex;
  gap: 2px;
  opacity: 0;
  pointer-events: none;
  padding-left: var(--sp-8);
  background: linear-gradient(90deg, transparent, var(--bg-grouped-secondary) 20%);
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.item-row:hover .quick, .item-row:focus-within .quick {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(-50%);
}

/* ========================================================================== */
/* Chips                                                                      */
/* ========================================================================== */

.chip {
  flex: 0 0 auto;
  font-size: 13px; line-height: 18px; letter-spacing: -0.0062em; font-weight: 500;
  padding: 2px var(--sp-2);
  border-radius: var(--r-pill);
  background: var(--fill-quaternary);
  color: var(--label-secondary);
  white-space: nowrap;
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chip-accent { background: var(--tint-soft);              color: var(--tint); }
.chip-green  { background: rgba(52, 199, 89, 0.16);        color: #248A3D; }
.chip-orange { background: rgba(255, 149, 0, 0.18);        color: #995200; }
.chip-red    { background: rgba(255, 59, 48, 0.15);        color: var(--red); }

@media (prefers-color-scheme: dark) {
  .chip-green  { background: rgba(48, 209, 88, 0.18);  color: var(--green); }
  .chip-orange { background: rgba(255, 159, 10, 0.20); color: var(--orange); }
}

/* ========================================================================== */
/* Sheets and modals                                                          */
/* ========================================================================== */

.scrim {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  /* Same reasoning as .auth-wrap: never clip the top of a tall sheet. */
  align-items: safe center;
  justify-items: center;
  padding: var(--sp-6);
  overflow-y: auto;
  background: rgba(0, 0, 0, 0.32);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: scrim-in var(--dur-fast) var(--ease-out);
}

.modal {
  width: 100%;
  max-width: 600px;
  max-height: min(88vh, 880px);
  display: flex;
  flex-direction: column;
  border-radius: var(--r-window);
  background: var(--mat-thick);
  backdrop-filter: blur(var(--blur-thick)) saturate(var(--sat));
  -webkit-backdrop-filter: blur(var(--blur-thick)) saturate(var(--sat));
  /* A sheet over a dimmed backdrop is one of the two places Apple does cast a
     shadow -- on macOS the window server draws it. */
  box-shadow:
    inset 0 1px 1px var(--rim-top),
    inset 0 -1px 1px var(--rim-under),
    var(--shadow-sheet);
  /* Rises and settles rather than fading — Apple's sheets have weight. */
  animation: modal-in var(--dur) var(--ease);
  overflow: hidden;
}

.modal > header {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-6) var(--sp-3);
}
.modal > header h3 { flex: 1; }
.modal .body { flex: 1 1 auto; overflow-y: auto; padding: var(--sp-3) var(--sp-6); overscroll-behavior: contain; }
.modal > footer {
  flex: 0 0 auto;
  display: flex;
  gap: var(--sp-3);
  justify-content: flex-end;
  padding: var(--sp-3) var(--sp-6) var(--sp-5);
}

@keyframes scrim-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes modal-in {
  from { opacity: 0; transform: translateY(20px) scale(0.96); }
  to   { opacity: 1; transform: none; }
}

/* ========================================================================== */
/* Sign-in screen                                                             */
/* ========================================================================== */

/**
 * Centred, but never clipped.
 *
 * Plain `place-items: center` centres by pushing equal space above and below —
 * so when the card is TALLER than the window, the overflow goes negative at the
 * top and the header is cut off with no way to scroll to it. Adding an error
 * banner is enough to trigger it on a short window.
 *
 * `safe center` falls back to start-alignment the moment content overflows, and
 * the wrapper scrolls, so the top is always reachable.
 */
.auth-wrap {
  min-height: 100vh;
  display: grid;
  align-items: safe center;
  justify-items: center;
  padding: var(--sp-6);
  overflow-y: auto;
}

.auth {
  width: 100%;
  max-width: 440px;
  padding: var(--sp-8);
  border-radius: var(--r-window);
  background: var(--mat-thick);
  backdrop-filter: blur(var(--blur-thick)) saturate(var(--sat));
  -webkit-backdrop-filter: blur(var(--blur-thick)) saturate(var(--sat));
  box-shadow: inset 0 1px 1px var(--rim-top), inset 0 -1px 1px var(--rim-under), var(--shadow-sheet);
  animation: modal-in var(--dur) var(--ease);
}

.auth .mark { display: flex; align-items: center; gap: var(--sp-4); margin-bottom: var(--sp-6); }
.auth .mark img { width: 52px; height: 52px; border-radius: 12px; }

/* ========================================================================== */
/* Banners                                                                    */
/* ========================================================================== */

.banner {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-4);
  border-radius: var(--r-field);
  font-size: 15px; line-height: 20px; letter-spacing: -0.0153em;
  margin-bottom: var(--sp-4);
}
.banner .ico { flex: 0 0 auto; margin-top: 1px; }
.banner-info  { background: var(--tint-soft);             color: var(--tint); }
.banner-ok    { background: rgba(52, 199, 89, 0.14);      color: #248A3D; }
.banner-warn  { background: rgba(255, 149, 0, 0.16);      color: #995200; }
.banner-error { background: rgba(255, 59, 48, 0.14);      color: var(--red); }

@media (prefers-color-scheme: dark) {
  .banner-ok   { background: rgba(48, 209, 88, 0.16);  color: var(--green); }
  .banner-warn { background: rgba(255, 159, 10, 0.16); color: var(--orange); }
}

/* ========================================================================== */
/* Stats and meters                                                           */
/* ========================================================================== */

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); gap: var(--sp-3); margin-bottom: var(--sp-4); }

.stat { padding: var(--sp-4) var(--sp-5); border-radius: var(--r-card); background: var(--bg-grouped-secondary); }
.stat.material { backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none; }
.stat.material::before, .stat.material::after { display: none; }
.stat b {
  display: block;
  font-size: 34px; line-height: 41px; letter-spacing: 0.0109em; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.stat span { color: var(--label-secondary); font-size: 13px; line-height: 18px; letter-spacing: -0.0062em; }
.stat.is-warn b { color: var(--orange); }
.stat.is-bad  b { color: var(--red); }
.stat.is-good b { color: var(--green); }

.strength { transition: opacity var(--dur-fast) var(--ease); }
.strength.is-empty { opacity: 0; height: 0; overflow: hidden; margin: 0; }

.meter { height: 6px; border-radius: var(--r-pill); background: var(--fill-tertiary); overflow: hidden; margin: var(--sp-2) 0 var(--sp-1); }
.meter i { display: block; height: 100%; border-radius: inherit; transition: width var(--dur) var(--ease), background var(--dur) var(--ease); }

/* ========================================================================== */
/* Tables                                                                     */
/* ========================================================================== */

table { width: 100%; border-collapse: collapse; }
th {
  text-align: left;
  padding: var(--sp-3) var(--sp-4);
  font-size: 13px; line-height: 18px;
  letter-spacing: 0.06em;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--label-secondary);
  box-shadow: inset 0 -0.5px 0 var(--separator);
}
td {
  padding: var(--sp-3) var(--sp-4);
  font-size: 15px; line-height: 20px; letter-spacing: -0.0153em;
  box-shadow: inset 0 -0.5px 0 var(--separator);
  vertical-align: middle;
}
tbody tr:last-child td { box-shadow: none; }
tbody tr { transition: background var(--dur-fast) var(--ease); }
tbody tr:hover { background: var(--fill-quaternary); }

code {
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  letter-spacing: 0;
  padding: 2px var(--sp-2);
  border-radius: var(--r-inner);
  background: var(--fill-tertiary);
  word-break: break-all;
}

/* ========================================================================== */
/* Enrolment code                                                             */
/* ========================================================================== */

.code-display {
  padding: var(--sp-5);
  border-radius: var(--r-field);
  background: var(--fill-quaternary);
  text-align: center;
  margin: var(--sp-4) 0;
}
.code-display .code {
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;
  font-size: 22px; line-height: 28px;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--tint);
  word-break: break-all;
}

/* ========================================================================== */
/* Empty states and toast                                                     */
/* ========================================================================== */

.empty { padding: var(--sp-12) var(--sp-6); text-align: center; }
.empty .glyph { display: flex; justify-content: center; opacity: 0.30; margin-bottom: var(--sp-3); color: var(--label-secondary); }
.empty .lead { font-size: 17px; line-height: 22px; letter-spacing: -0.0253em; font-weight: 600; margin-bottom: var(--sp-1); }
.empty .sub {
  color: var(--label-secondary);
  font-size: 15px; line-height: 20px; letter-spacing: -0.0153em;
  max-width: 420px; margin: 0 auto;
}

.toast {
  position: fixed;
  bottom: var(--sp-8);
  left: 50%;
  z-index: 200;
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--r-pill);
  background: var(--mat-thick);
  backdrop-filter: blur(var(--blur-thick)) saturate(var(--sat));
  -webkit-backdrop-filter: blur(var(--blur-thick)) saturate(var(--sat));
  box-shadow: inset 0 1px 0 var(--rim-top), inset 0 0 0 0.5px var(--rim-hair);
  font-size: 15px; line-height: 20px; letter-spacing: -0.0153em; font-weight: 500;
  pointer-events: none;
  transform: translateX(-50%);
  animation: toast-in var(--dur) var(--ease);
}
@keyframes toast-in {
  from { opacity: 0; transform: translate(-50%, 16px) scale(0.94); }
  to   { opacity: 1; transform: translate(-50%, 0) scale(1); }
}

.boot { display: grid; place-items: center; min-height: 100vh; color: var(--label-secondary); }

/* ========================================================================== */
/* Utilities                                                                  */
/*                                                                            */
/* The page ships `style-src 'self'`, which blocks inline style attributes —   */
/* the right trade for a page holding a decrypted vault. So one-off spacing    */
/* is named, and every value comes off the 8pt grid.                           */
/* ========================================================================== */

.w-full     { width: 100%; }
.push       { margin-right: auto; }
.flush      { margin: 0; }
.tight-top  { margin-top: calc(var(--sp-2) * -1); margin-bottom: var(--sp-5); }
.mt-1       { margin-top: var(--sp-1); }
.mt-2       { margin-top: var(--sp-2); }
.mt-3       { margin-top: var(--sp-3); }
.mb-2       { margin: 0 0 var(--sp-2); }
.mb-3       { margin: 0 0 var(--sp-3); }
.mb-4       { margin: 0 0 var(--sp-4); }
.text-right { text-align: right; }
.static-row { cursor: default; }
.strong     { font-weight: 600; }
/* Flex row: the global `svg { display: block }` (which stops icons being
   squashed in flex parents) otherwise pushes the tick onto its own line. */
.ok-text {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  color: var(--green);
  font-weight: 500;
  font-size: 15px; line-height: 20px; letter-spacing: -0.0153em;
}
.muted      { color: var(--label-secondary); }
.subtle     { color: var(--label-secondary); font-size: 15px; line-height: 20px; letter-spacing: -0.0153em; }
.caption    { color: var(--label-secondary); font-size: 13px; line-height: 18px; letter-spacing: -0.0062em; }
.row-end    { display: flex; gap: var(--sp-2); justify-content: flex-end; }
.row-fit    { display: flex; gap: var(--sp-2); flex: 0 0 auto; }
.narrow     { max-width: 540px; }
.brand-title{ font-size: 28px; line-height: 34px; letter-spacing: 0.0129em; font-weight: 700; }
.sep-top    { box-shadow: inset 0 0.5px 0 var(--separator); }
.section-break { margin-top: var(--sp-6); padding-top: var(--sp-5); box-shadow: inset 0 0.5px 0 var(--separator); }

.fingerprint {
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  letter-spacing: 0;
  color: var(--label-secondary);
}

details > summary {
  cursor: pointer;
  font-size: 15px; line-height: 20px; letter-spacing: -0.0153em;
  color: var(--label-secondary);
  list-style: none;
  padding: var(--sp-1) 0;
}
details > summary::-webkit-details-marker { display: none; }
details > summary::before { content: '▸ '; }
details[open] > summary::before { content: '▾ '; }

/* ========================================================================== */
/* Responsive                                                                 */
/* ========================================================================== */

@media (max-width: 900px) {
  .shell { grid-template-columns: 1fr; }
  .sidebar { position: static; height: auto; }
  .grid2 { grid-template-columns: 1fr; }
  .content { padding: var(--sp-2) 0 var(--sp-10); }
}

/* Visually and interactively hidden, but still clickable via .click(). Used
   for the file input behind the "Choose a file" button. */
.hidden { display: none; }
