/* ==========================================================================
   Keel — the app layers on top of Deck
   --------------------------------------------------------------------------
   deck.css declares the cascade order: every deck.* layer first, then
   app.base, app.components, app.pages, app.overrides. A rule in one of those
   beats any Deck rule with no !important and no specificity games, as long as
   this file loads after deck.css (views/partials/head.php guarantees that).
   Loaded first, these @layer blocks would declare the order themselves and
   Deck would win everything.

   Never edit public_html/deck/: Composer republishes it on every install.
   ========================================================================== */

@layer app.base {
  :root {
    /* Keel's brand colour, #ff6b3d, is oklch(70.5% .191 37.5) — hue 38.
       A tenant's organizations.brand_hue replaces this with an inline style on
       <html>, which outranks every layer. */
    --hue-brand: 38;
  }

  /* Deck's reset has no [hidden] rule, so any Deck class that sets display
     (.btn, .card, .stack, ...) overrides the attribute and the element stays
     on screen. app.base sits after every deck.* layer, so this wins. */
  [hidden] { display: none; }
}

@layer app.components {
  /* A table inside a card. .table-wrap brings its own border and radius, so
     inside a .card it draws a second frame one pixel in from the first. */
  .card > .table-wrap {
    border: 0;
    border-radius: 0;
  }

  @media (max-width: 39.999rem) {
    /* Below 40rem .table-stack turns each row into a bordered box. Flush with
       the card's edge that reads as a border on a border, and the last box
       keeps its bottom margin, leaving a strip above the card's own border. */
    .card > .table-wrap:has(> .table-stack) { padding: var(--space-3); }
    .table-stack tbody tr:last-child { margin-block-end: 0; }
  }

  /* The cell that holds an .empty state across every column. Deck has
     .dg-empty for the data grid and nothing for .table: the cell padding
     stacks on the empty state's own, the row picks up the hover tint, and
     .table-stack turns the cell into a label/value row with no label. */
  .table .table-empty { padding: 0; }
  .table tbody tr:has(> .table-empty):hover { background: none; }
  @media (max-width: 39.999rem) {
    .table-stack tr:has(> .table-empty) { border: 0; padding: 0; }
    .table-stack .table-empty { display: block; }
    .table-stack .table-empty::before { content: none; }
  }

  /* Two-state marks: the moon and sun in the theme switch, and the two logo
     files. [data-deck-theme] flips the theme but exposes no state, so the mark
     that suits the theme in effect is the one shown — the attribute when one is
     set, the OS preference when not. revert-layer hands display back to whatever
     Deck's own layers set, which differs between an <svg> and an <img>. */
  .when-dark { display: none; }
  :root[data-theme="dark"] .when-light { display: none; }
  :root[data-theme="dark"] .when-dark { display: revert-layer; }
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme]) .when-light { display: none; }
    :root:not([data-theme]) .when-dark { display: revert-layer; }
  }

  /* The theme switch on a page with no header to hang it on: errors, billing
     results, sign-in. Keel used to inject a floating switch on every page that
     had none, and this is the same corner. */
  .theme-toggle-floating {
    position: fixed;
    inset-block-start: var(--space-4);
    inset-inline-end: var(--space-4);
    z-index: var(--z-nav);
    background: var(--surface);
    border-color: var(--line);
    box-shadow: var(--shadow-1);
  }

  /* The wordmark and the app icon are raster files far larger than they render,
     so the height is set here rather than per view. */
  .brand-logo {
    block-size: 2.5rem;
    inline-size: auto;
    object-fit: contain;
  }

  /* A tenant's brand hue, as a dot beside its name. Deck computes its brand ramp once on
     :root, so a page listing several tenants cannot preview each one by setting
     --hue-brand on a row. This rebuilds just the fill from the lightness and chroma Deck
     uses for --brand-600: the one place Keel repeats a Deck value instead of reading it. */
  .hue-swatch {
    display: inline-block;
    inline-size: .75rem;
    block-size: .75rem;
    border-radius: var(--r-full);
    background: oklch(51.6% .118 var(--hue, 196));
    vertical-align: -.05em;
  }

  /* A six-digit code, spaced so it reads as digits rather than a word. */
  .otp-input {
    text-align: center;
    letter-spacing: .42em;
    font-variant-numeric: tabular-nums;
  }
}

@layer app.pages {
  /* Keel's settings pages: a 64rem column beside a 24rem rail. Deck's container
     steps are 40, 56, 76 and 90rem and .split's rail is a fixed width, so both
     are set once here rather than per view. .section is page rhythm for
     marketing pages (about 6rem at desktop); an app screen wants 2.5rem. */
  .settings-page {
    --container: 64rem;
    --rail: 24rem;
    padding-block: var(--space-10);
  }

  /* The docs rail: a column beside the article, and one scrollable row above it on a
     phone. Deck's .sidebar is always a column and .scroller is its row equivalent, so the
     switch is a media query rather than the JavaScript toggle the previous layout used.
     Group headings drop out of the row, where the labels have to carry themselves. */
  @media (max-width: 63.999rem) {
    .docs-sections .sidebar {
      flex-direction: row;
      overflow-x: auto;
      scrollbar-width: none;
    }
    .docs-sections .sidebar-group { display: none; }
    .docs-sections .sidebar-link { white-space: nowrap; }
  }

  /* One card centred in the viewport: errors, billing results, sign-in,
     onboarding. --stage-width widens it for a page that needs more room. */
  .stage {
    display: grid;
    place-items: center;
    min-block-size: 100dvh;
    padding-block: var(--space-10);
  }
  .stage > * { inline-size: min(100%, var(--stage-width, 34rem)); }
}
