/* InsightKit dashboard theme and layout, on top of Basecoat (shadcn/ui as
   plain CSS — see basecoat/README.md), styled with the Graphite design system
   (graphite-design-system/ in the repository root).

   Four rules for this file:

   1. Components come from Basecoat: .btn, .card, .badge, .alert, .table,
      .field, .input, .dialog, .dropdown-menu, .sidebar, .breadcrumb, .empty.
      Their Graphite shape (pills, no shadows) is set in the "Graphite shape"
      block below, inside @layer components. Basecoat's rules sit in CSS
      layers, and any unlayered rule in this file beats them regardless of
      specificity — so a generic unlayered rule (button, table, .btn …)
      silently replaces shadcn's. Keep component overrides in the layer.
   2. This file holds the theme, the page layout (Basecoat ships no layout
      utilities), and the few things that are InsightKit's own: request status
      (Ch. 12 §3), "soon" placeholders, app avatars, vote counts.
   3. Colours are tokens. Nothing here names a hex value except the theme
      blocks below and the avatar greys.
   4. Graphite is monochrome. The only hue is the InsightKit orange, and it is
      used for the logo only (--logo-accent). Green is the "live" dot and red
      is destructive; nothing else has a colour. Meaning is carried by text,
      weight and fill, never by colour alone. */

/* ---- font ---------------------------------------------------------------- */

/* Geist, variable 100–900, served from this binary (fonts/Geist-OFL.txt).
   Named "Geist Sans" because Basecoat's --font-sans already asks for it. */
@font-face {
  font-family: "Geist Sans";
  src: url("fonts/Geist-Variable.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}

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

/* Graphite tokens, mapped onto the shadcn names Basecoat reads.
   background → surface → surface-muted are the fill steps that separate
   things; there are no shadows. */
:root {
  --font-sans: "Geist Sans", ui-sans-serif, system-ui, sans-serif;
  --default-font-family: var(--font-sans);

  /* --radius-xl (cards) = radius + 4px = Graphite's radius-card, 18px. */
  --radius: 14px;
  --radius-full: 9999px;

  --background: #efefef;
  --foreground: #232323;
  --card: #ffffff;
  --card-foreground: #232323;
  --popover: #ffffff;
  --popover-foreground: #232323;
  --primary: #232323;
  --primary-foreground: #efefef;
  --secondary: #f5f5f5;
  --secondary-foreground: #000000;
  --muted: #f5f5f5;
  --muted-foreground: #707070;
  --accent: #f5f5f5;
  --accent-foreground: #232323;
  --destructive: #e40014;
  --border: #e5e5e5;
  --input: #dcdcdc;
  --ring: #a1a1a1;
  --sidebar: #efefef;
  --sidebar-foreground: #232323;
  --sidebar-primary: #232323;
  --sidebar-primary-foreground: #efefef;
  --sidebar-accent: #ffffff;
  --sidebar-accent-foreground: #000000;
  --sidebar-border: #e5e5e5;
  --sidebar-ring: #a1a1a1;

  /* Graphite's own names. */
  --foreground-strong: #000000;
  --logo: #b4b4b4;
  --success: #1daf61;
  --focus-ring: 0 0 0 2px var(--background), 0 0 0 4px var(--foreground);

  /* The InsightKit orange. The logo only: the "Kit" of the wordmark in the
     sidebar and on the sign-in page. Do not use it for anything else. */
  --logo-accent: #b45309;

  /* App roles, all monochrome now. --brand used to be the orange for links
     and counts; it is kept as a name so older inline styles still work. */
  --brand: var(--foreground-strong);
  --status-blue: var(--foreground);
  --status-green: var(--success);
  --status-red: var(--destructive);
  --soon: var(--muted-foreground);
}

.dark {
  /* Graphite's dark theme: grey, not black (also Ch. 12 §3). */
  --background: #232323;
  --foreground: #efefef;
  --card: #313131;
  --card-foreground: #efefef;
  --popover: #313131;
  --popover-foreground: #efefef;
  --primary: #efefef;
  --primary-foreground: #232323;
  --secondary: #3a3a3a;
  --secondary-foreground: #efefef;
  --muted: #2e2e2e;
  --muted-foreground: #9d9d9d;
  --accent: #3a3a3a;
  --accent-foreground: #efefef;
  /* Graphite's red is for light grounds: #e40014 on the dark card #313131 is
     2.67:1. This lighter red is 4.88:1 there and 5.89:1 on #232323. */
  --destructive: #ff7176;
  --border: #3a3a3a;
  --input: #474747;
  --ring: #707070;
  --sidebar: #232323;
  --sidebar-foreground: #efefef;
  --sidebar-primary: #efefef;
  --sidebar-primary-foreground: #232323;
  --sidebar-accent: #313131;
  --sidebar-accent-foreground: #efefef;
  --sidebar-border: #3a3a3a;
  --sidebar-ring: #707070;

  --foreground-strong: #efefef;
  --logo: #5a5a5a;

  --logo-accent: #f0a04b;
}

/* The names the templates used before Basecoat, kept as aliases so older
   inline styles follow the theme in both modes. New code should use the
   shadcn names directly. */
:root {
  --bg: var(--background);
  --panel: var(--card);
  --raised: var(--muted);
  --line: var(--border);
  --line-soft: color-mix(in oklab, var(--border) 65%, transparent);
  --fg: var(--foreground);
  --dim: var(--muted-foreground);
  --faint: var(--muted-foreground);
  --blue: var(--status-blue);
  --green: var(--status-green);
  --red: var(--status-red);
}

/* ---- base ----------------------------------------------------------------- */

/* In the base layer, so Basecoat's components (a later layer) win over it:
   an unlayered "a { color: inherit }" would recolour every <a class="btn">. */
@layer base {
  body {
    font-family: var(--font-sans); font-size: 14px; line-height: 1.55; font-weight: 500;
    background: var(--background); color: var(--foreground); -webkit-font-smoothing: antialiased;
  }
  a { color: inherit; text-decoration: none; }
  h1, h2, h3 { font-weight: 700; }
  code, pre { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
  pre {
    background: var(--muted); border: 0; border-radius: var(--radius-lg);
    padding: 12px 14px; overflow-x: auto; font-size: 12.5px; line-height: 1.6; margin: 0;
  }
}
.grow { flex: 1; min-width: 0; }
.hot { color: var(--foreground-strong); font-weight: 700; }
.quiet { color: var(--faint); font-size: 13px; }
/* A text link inside running copy. Monochrome, so the underline is what
   marks it as a link. */
.link { color: var(--foreground-strong); text-decoration: underline; text-decoration-color: var(--ring); text-underline-offset: 2px; }
.link:hover { text-decoration-color: currentColor; }

/* ---- Graphite shape ------------------------------------------------------- */
/* Same layer as Basecoat's components and loaded after them, so these win at
   equal specificity and Basecoat's variants still apply on top. */
@layer components {
  /* Anything you can press is a pill. */
  .btn {
    border-radius: var(--radius-full); font-weight: 600;
    transition: background-color .3s cubic-bezier(.76,0,.24,1), color .3s cubic-bezier(.76,0,.24,1), transform .3s cubic-bezier(.76,0,.24,1);
  }
  .btn:not(:disabled):hover { transform: translateY(-1px); }
  .btn:active { transform: none; }
  .btn:focus-visible { outline: 2px solid transparent; border-color: transparent; box-shadow: var(--focus-ring); }
  .badge { border-radius: var(--radius-full); font-weight: 600; }

  /* No shadows, almost no borders: a card is a fill step above the page. */
  .card { box-shadow: none; border-color: transparent; }
  .alert { border-radius: var(--radius-lg); }
  .input, .select, .textarea, input.input, select.select, textarea.textarea { border-radius: 10px; box-shadow: none; }
  .input:focus-visible, .select:focus-visible, .textarea:focus-visible { box-shadow: var(--focus-ring); border-color: transparent; }

  /* Floating layers keep a hairline so they separate from what is under them. */
  .dialog > div, [data-popover] { box-shadow: none; border: 1px solid var(--border); }
  .dialog > div { border-radius: var(--radius-lg); }
}

/* ---- frame: sidebar, top bar, app header ---------------------------------- */

.sidebar .brand { display: block; padding: 16px 16px 10px; font-weight: 700; font-size: 16px; letter-spacing: -.48px; }
.sidebar .brand span { color: var(--logo-accent); }
.sidebar nav > section { padding: 0 8px 12px; }
.sidebar h3 { padding: 0 10px; margin: 14px 0 4px; font-size: 12px; font-weight: 500; color: var(--muted-foreground); }
.sidebar ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.sidebar li > a, .sidebar li > span {
  display: flex; align-items: center; gap: 9px; padding: 6px 10px; border-radius: var(--radius-full);
  font-size: 14px; font-weight: 500; color: var(--muted-foreground);
  transition: color .5s cubic-bezier(.7,0,0,1), background-color .5s cubic-bezier(.7,0,0,1);
}
.sidebar li > a:hover { color: var(--sidebar-foreground); }
.sidebar li > a[aria-current] { background: var(--sidebar-accent); color: var(--sidebar-accent-foreground); font-weight: 600; }
.sidebar li > span.soon { color: var(--muted-foreground); border: 0; }
/* Counts are small dark chips (Graphite's Tag), not coloured numbers. */
.sidebar .n, .apptabs .count {
  display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 18px; padding: 0 6px;
  border-radius: var(--radius-full); background: var(--primary); color: var(--primary-foreground);
  font-variant-numeric: tabular-nums; font-size: 11px; font-weight: 700; line-height: 1;
}
.sidebar .n { margin-left: auto; }
.sidebar .add { justify-content: center; margin-top: 6px; border: 1px dashed var(--border); }

.topbar {
  position: sticky; top: 0; z-index: 30; height: 56px; padding: 0 16px;
  display: flex; align-items: center; gap: 8px;
  background: var(--background);
}
.topbar svg { width: 16px; height: 16px; }
.iconbtn { position: relative; }
.iconbtn .soon-badge { position: absolute; top: -8px; right: -10px; font-size: 8px; padding: 0 4px; background: var(--background); }
.userchip { display: flex; align-items: center; gap: 9px; text-align: left; }
.userchip .face {
  width: 26px; height: 26px; border-radius: 50%; background: var(--primary); display: flex;
  align-items: center; justify-content: center; font-size: 12px; font-weight: 700; color: var(--primary-foreground);
}
/* The Google profile photo (US-01 c9): cropped to the circle, never stretched. */
.userchip img.face { object-fit: cover; background: var(--muted); flex-shrink: 0; }
.userchip .who { display: flex; flex-direction: column; line-height: 1.2; }
.userchip .who b { font-weight: 600; font-size: 13px; max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.userchip .who small { color: var(--muted-foreground); font-size: 11px; font-weight: 500; }

.apphead { padding: 12px 20px 0; }
.apphead .breadcrumb { margin-bottom: 8px; }
.apptitle { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.apptitle h1 { margin: 0; font-size: 26px; font-weight: 700; letter-spacing: -.78px; }
.apptitle .meta { margin-left: auto; color: var(--muted-foreground); font-size: 12px; display: flex; gap: 8px; align-items: center; }

/* App tabs are links to separate pages, so they are a <nav> with
   aria-current, not ARIA tabs (Basecoat's .tabs switches panels in one page).
   Styled as Graphite's nav: muted links in a pill, the current one filled. */
.apptabs {
  display: inline-flex; gap: 2px; margin-top: 14px; flex-wrap: wrap; padding: 4px;
  background: var(--card); border-radius: var(--radius-full);
}
.apptabs > a, .apptabs > span {
  display: inline-flex; gap: 6px; align-items: center; padding: 6px 14px; border-radius: var(--radius-full);
  font-size: 13px; font-weight: 500; color: var(--muted-foreground);
  transition: color .5s cubic-bezier(.7,0,0,1), background-color .5s cubic-bezier(.7,0,0,1);
}
.apptabs > a:hover { color: var(--foreground); }
.apptabs > a[aria-current] { color: var(--primary-foreground); background: var(--primary); font-weight: 600; }
.apptabs > a[aria-current] .count { background: var(--primary-foreground); color: var(--primary); }
.apptabs > span.soon { border: 0; }

main { padding: 20px 20px 60px; max-width: 1180px; min-width: 0; }
main > .alert { margin-bottom: 14px; }

/* ---- page parts ----------------------------------------------------------- */

.head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.head h1 { font-size: 22px; margin: 0; font-weight: 700; letter-spacing: -.66px; }
.head .sub { color: var(--muted-foreground); font-size: 13px; }
.head .right { margin-left: auto; display: flex; gap: 8px; align-items: center; }
.row { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; }
.stack { display: flex; flex-direction: column; gap: 12px; }
.card + .card { margin-top: 12px; }
.card > header > h2 { font-size: 16px; font-weight: 700; letter-spacing: -.32px; }
.field + .field { margin-top: 12px; }
form .field:last-of-type { margin-bottom: 12px; }

/* Status filters: a pill track, the current item filled. */
.filters {
  display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 4px; margin-bottom: 12px;
  background: var(--card); border-radius: var(--radius-full);
}
.filters a { font-size: 13px; font-weight: 500; padding: 4px 12px; border-radius: var(--radius-full); color: var(--muted-foreground); }
.filters a:hover { color: var(--foreground); }
.filters a[aria-current] { background: var(--primary); color: var(--primary-foreground); font-weight: 600; }

/* Tables: Basecoat's .table, with the dashboard's density (Ch. 12 §5:
   15+ rows visible). */
.table th { font-size: 12px; font-weight: 500; color: var(--muted-foreground); text-align: left; }
.table td.wrap, .table td.title { white-space: normal; }
.table tr.dim td { opacity: .55; }
.table.boxed { background: var(--card); border-radius: var(--radius-xl); border-collapse: separate; border-spacing: 0; overflow: hidden; }
.votes {
  display: inline-flex; min-width: 34px; justify-content: center; padding: 2px 8px;
  border-radius: var(--radius-full);
  font-variant-numeric: tabular-nums; font-size: 13px; font-weight: 700; background: var(--muted);
}
.title { font-size: 14px; }
.title a:hover { text-decoration: underline; }
.tags { display: inline-flex; gap: 6px; margin-left: 8px; vertical-align: middle; }
.when { color: var(--muted-foreground); font-size: 12px; white-space: nowrap; }
table.facts { border-collapse: collapse; }
table.facts td { padding: 5px 0; font-size: 13px; vertical-align: top; }
table.facts td:first-child { color: var(--muted-foreground); width: 160px; }

/* Request status. Always a text label — colour is never the signal. Planned
   is plain, In progress is filled, Shipped gets the green live dot, and a
   decline is quiet rather than red (Ch. 12 §3). */
.badge.status.planned { color: var(--foreground); }
.badge.status.in_progress { color: var(--primary-foreground); background: var(--primary); border-color: var(--primary); }
.badge.status.declined, .badge.status.closed { color: var(--muted-foreground); }
.badge.status.shipped::before, .badge.live::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--success); flex: none;
}
.badge.status.shipped, .badge.live { color: var(--foreground); }
select.select.status { width: auto; }
select.select.status.in_progress, select.select.status.shipped { font-weight: 600; }
.badge.nosdk { border-style: dashed; color: var(--muted-foreground); }

/* ---- app icon drop zone --------------------------------------------------- */
/* Shared by "Add app" and Setup & keys, with its script in icondrop.js, so the
   two pages pick an icon the same way. The zone is a <label> around the real
   file input, so a click, the keyboard and a drag all end in the same input.
   .has: an icon is shown (a chosen file, or the app's current icon).
   .chosen: a new file is chosen and not saved yet. */
.drop { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; width: 148px; height: 148px; border: 1.5px dashed var(--ring); border-radius: 22px;
  background: var(--muted); color: var(--dim); cursor: pointer; text-align: center;
  transition: border-color .12s, background .12s, transform .12s; }
.drop:hover, .drop:focus-within { border-color: var(--foreground); }
.drop:focus-within { outline: 2px solid transparent; box-shadow: var(--focus-ring); }
.drop.over { border-color: var(--foreground); border-style: solid; transform: scale(1.03);
  background: var(--accent); }
.drop input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.drop svg { width: 26px; height: 26px; }
.drop .hint { font-size: 12px; line-height: 1.35; padding: 0 10px; }
.drop .hint b { color: var(--foreground); font-weight: 600; }
/* The preview uses the same rounded-square shape as an iOS icon. */
.drop img { display: none; width: 96px; height: 96px; border-radius: 22%; object-fit: cover; }
.drop.has img { display: block; }
.drop .empty-state { display: contents; }
.drop.has .empty-state { display: none; }
.drop .fname { display: none; font-size: 11px; max-width: 128px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drop.chosen .fname { display: block; }
.drop .clear { display: none; position: absolute; top: -8px; right: -8px; width: 24px; height: 24px; border-radius: 50%;
  border: 0; background: var(--primary); color: var(--primary-foreground); font-size: 15px; line-height: 1;
  cursor: pointer; }
.drop.chosen .clear { display: block; }
.drop .clear:hover { opacity: .85; }


/* Setup & keys: the zone on the left, text and buttons on the right. */
.icongrid { display: grid; grid-template-columns: 148px 1fr; gap: 22px; align-items: start; }
@media (max-width: 640px) { .icongrid { grid-template-columns: 1fr; } }
.icongrid .help { color: var(--faint); font-size: 12px; margin: 6px 0 0; }
.icongrid .err { display: none; color: var(--destructive); font-size: 12px; margin: 8px 0 0; }
.icongrid .err.on { display: block; }
.icongrid .actions { display: flex; align-items: center; gap: 8px; margin-top: 14px; flex-wrap: wrap; }

/* Sandbox / Production switch next to the app name, and the bar shown while
   Sandbox is on. Sandbox is shown inverted (a dark fill in the light theme, a
   light fill in the dark one) so it cannot be missed without a colour; the
   label, not the fill, carries the meaning. */
.envswitch { display: inline-flex; background: var(--card); border-radius: var(--radius-full); padding: 3px; gap: 2px; }
.envswitch button {
  border: 0; background: none; cursor: pointer; font: inherit; font-size: 12px; font-weight: 500;
  padding: 3px 12px; border-radius: var(--radius-full); color: var(--muted-foreground);
}
.envswitch button:hover { color: var(--foreground); }
.envswitch button:focus-visible { outline: 2px solid transparent; box-shadow: var(--focus-ring); }
.envswitch button[aria-pressed="true"] { background: var(--muted); color: var(--foreground); font-weight: 600; }
.envswitch button.sandbox[aria-pressed="true"] { background: var(--primary); color: var(--primary-foreground); }
.sandbox-bar {
  margin-top: 10px; padding: 8px 16px; font-size: 13px; border-radius: var(--radius-full);
  background: var(--primary); color: var(--primary-foreground);
}
.sandbox-bar strong { font-weight: 700; }
.sandbox-bar code { color: inherit; }
.badge.sandbox { background: var(--primary); color: var(--primary-foreground); border-color: var(--primary); }

.key {
  display: flex; gap: 8px; align-items: center; background: var(--muted);
  border-radius: 10px; padding: 8px 12px;
  font-family: ui-monospace, Menlo, monospace; font-size: 12.5px; word-break: break-all;
}
.linkbtn { background: none; border: 0; padding: 0; cursor: pointer; font: inherit; font-size: 13px; font-weight: 600;
  color: var(--foreground-strong); text-decoration: underline; text-decoration-color: var(--ring); text-underline-offset: 2px; }
.linkbtn:hover { text-decoration-color: currentColor; }

/* Placeholders for what is not built yet: the same dashed grey outline and a
   "soon" badge everywhere, and they do nothing when clicked. */
.soon { border: 1px dashed var(--soon); cursor: default; }
.soon-badge {
  display: inline-block; font-size: 9.5px; font-weight: 700; letter-spacing: .3px; text-transform: uppercase;
  padding: 1px 7px; border: 1px dashed var(--soon); border-radius: var(--radius-full); color: var(--soon);
  vertical-align: middle; line-height: 1.5;
}
.soonline { color: var(--muted-foreground); font-size: 12px; margin: 8px 0 0; }

/* App avatar: the first letter on one of six greys, fixed per app. */
.av {
  width: 22px; height: 22px; border-radius: 6px; flex: none; display: inline-flex;
  align-items: center; justify-content: center; font-size: 12px; font-weight: 700; color: #ffffff;
}
.av.big { width: 40px; height: 40px; font-size: 20px; border-radius: 10px; }
.av.t0 { background: #232323; } .av.t1 { background: #4a4a4a; } .av.t2 { background: #5f5f5f; }
.av.t3 { background: #363636; } .av.t4 { background: #6e6e6e; } .av.t5 { background: #545454; }
.dark .av.t0 { background: #5a5a5a; }

/* ---- Home and app Overview ----------------------------------------------- */

.callout > section { display: flex; align-items: center; gap: 16px; }
.callout.attention { background: var(--primary); color: var(--primary-foreground); }
.callout.attention .sub { color: inherit; opacity: .75; }
/* The callout is inverted, so its primary button is inverted again. */
.callout.attention .btn { background: var(--primary-foreground); color: var(--primary); }
.callout .big { font-size: 36px; font-weight: 700; letter-spacing: -1.08px; font-variant-numeric: tabular-nums; min-width: 28px; }
.callout strong { display: block; font-weight: 700; font-size: 16px; }
.callout .sub { color: var(--muted-foreground); font-size: 13px; }
.callout { margin-bottom: 18px; }
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; margin-bottom: 26px; }
.cards > .card { margin: 0; transition: transform .3s cubic-bezier(.76,0,.24,1); }
.cards > .card:hover { transform: translateY(-2px); }
.cards > .card.pending { background: transparent; border: 1.5px dashed var(--ring); }
.cardhead { display: flex; align-items: center; gap: 10px; }
.cardhead .name { flex: 1; font-weight: 700; font-size: 16px; letter-spacing: -.32px; line-height: 1.25; }
.cardhead .av.big { width: 34px; height: 34px; font-size: 17px; }
.nums { display: flex; gap: 22px; margin-bottom: 8px; }
.num { display: block; font-size: 28px; font-weight: 700; letter-spacing: -.84px; font-variant-numeric: tabular-nums; line-height: 1.1; }
.num.hot { color: var(--foreground-strong); }
.nums small { color: var(--muted-foreground); font-size: 12px; }
.card .line { margin: 4px 0 0; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card .line.dim { color: var(--muted-foreground); }
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; }
.sechead { display: flex; align-items: baseline; gap: 10px; margin-bottom: 8px; }
.sechead h2 { font-size: 16px; font-weight: 700; letter-spacing: -.32px; margin: 0; }
.sechead .sub { margin-left: auto; color: var(--muted-foreground); font-size: 12px; }
.sechead a.sub:hover { color: var(--foreground); }
.activity, .toplist, .checks { list-style: none; margin: 0; padding: 0; }
.activity li, .toplist li { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--line-soft); font-size: 13px; }
.activity .when { width: 64px; flex: none; }
.activity .grow, .toplist .grow { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.activity a:hover, .toplist a:hover { text-decoration: underline; }
.appref { display: inline-flex; align-items: center; gap: 6px; color: var(--muted-foreground); font-size: 12px; white-space: nowrap; }
.appref .av, .activity .av { width: 18px; height: 18px; font-size: 10px; }
.checks li { padding: 4px 0; color: var(--muted-foreground); font-size: 13px; }
.checks li.ok { color: var(--foreground); }
.checks a { color: var(--foreground-strong); font-weight: 600; text-decoration: underline; text-decoration-color: var(--ring); text-underline-offset: 2px; }
.checks a:hover { text-decoration-color: currentColor; }

/* ---- dialogs ------------------------------------------------------------- */

/* The delete dialog sits inside a table cell on the board and in the inbox,
   and Basecoat's .table td is nowrap. Without this its text runs out of the box. */
.dialog { white-space: normal; }
.dialog p { color: var(--muted-foreground); font-size: 13px; margin: 0 0 8px; line-height: 1.5; }
.dialog footer { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; }

/* ---- small screens -------------------------------------------------------- */

@media (max-width: 960px) { .split { grid-template-columns: 1fr; } }
/* Ch. 15 §5 and US-23 c5: the ticket reply flow must work at phone width. */
@media (max-width: 720px) {
  main { padding: 14px 12px 40px; }
  .apphead { padding: 12px 12px 0; }
  .apptabs { border-radius: var(--radius-lg); }
  th.hide-sm, td.hide-sm { display: none; }
  .userchip .who { display: none; }
}

/* The theme switch labels itself for the theme it switches TO. */
.dark .theme-light-only, :root:not(.dark) .theme-dark-only { display: none; }

/* shadcn's Empty is shown with a dashed border in its docs (a utility class
   there). Basecoat ships no utilities, so it is a named modifier here.
   Empty states stay text only — no illustration (Ch. 12 §4). */
.empty.dashed { border: 1.5px dashed var(--ring); border-radius: var(--radius-xl); padding: 36px 24px; }
.empty h3 { font-size: 16px; font-weight: 700; letter-spacing: -.32px; margin: 0 0 6px; }
.empty p { color: var(--muted-foreground); font-size: 13px; margin: 0; }
.empty footer { margin-top: 14px; }
/* Status dropdowns in board rows: wide enough for "In Progress" plus the arrow. */
.table select.select.status { min-width: 132px; }

/* An uploaded app icon in place of the letter avatar: same box, image fills
   it. object-fit keeps a non-square upload from stretching. */
img.av { object-fit: cover; background: var(--muted); }
img.av.big { border-radius: 10px; }
