/* SPDX-License-Identifier: Apache-2.0 */
/* OpenRun brand layer for action apps, ported from the management console
   (ui/console/static/css/style.css) and the list_apps app. Theme colors come
   from the daisyui themes (openrun-light/openrun-dark by default, or the
   app's own style config); everything here uses theme variables so it
   adapts to light/dark. */

/* ---- Typography ---------------------------------------------------------
   Self-hosted brand type (SIL OFL, woff2 in astatic/fonts/): Space Grotesk
   for headings, Inter for body, JetBrains Mono for identifiers and report
   values. The @font-face declarations live in the layout template
   (layout.go.html "fonts" block), NOT here: a static css file can only
   reference the fonts by their plain names, while the template's astatic
   helper emits content-hashed urls which get immutable caching. The
   generated tailwind layer routes every font through
   --font-sans/--font-mono, so redefining the variables here covers the
   preflight body default and the font-sans/font-mono utilities alike.
   Shipped weights only: Inter 400/500/600, Space Grotesk 500/700,
   JetBrains Mono 400/500. */

:root {
  --ease-out-soft: cubic-bezier(0.22, 1, 0.36, 1);
  --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif,
    "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
    "Noto Color Emoji";
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Monaco,
    Consolas, "Liberation Mono", "Courier New", monospace;
}

/* Headings carry the display face. Unlayered rule (beats layered tailwind
   utilities), so mono headings must be excluded explicitly */
h1:not(.font-mono),
h2:not(.font-mono),
h3:not(.font-mono),
.page-title {
  font-family: "Space Grotesk", var(--font-sans);
}

/* ---- AA-safe brand green text ------------------------------------------
   The brand light green (--color-primary) is a FILL color: as text on
   light surfaces it fails AA. --or-accent-text is the readable brand
   accent for text in the active theme: the darker secondary on light
   surfaces, the bright primary on dark. color-scheme comes from the
   active daisyui theme, so this follows any theme without hardcoding
   theme names. */
:root {
  --or-accent-text: var(--color-secondary);
}
@media (prefers-color-scheme: dark) {
  :root {
    --or-accent-text: var(--color-primary);
  }
}
:root[data-color-scheme="light"] {
  --or-accent-text: var(--color-secondary);
}
:root[data-color-scheme="dark"] {
  --or-accent-text: var(--color-primary);
}
.text-primary,
.link-primary {
  color: var(--or-accent-text);
}

/* ---- Page title ---------------------------------------------------------
   The heading carries the brand accent fade bar, matching the console
   screens. */
.page-title::after {
  content: "";
  display: block;
  width: 4.3em;
  height: 3px;
  margin-top: 0.3rem;
  border-radius: 2px;
  background: linear-gradient(
    90deg,
    color-mix(in oklch, var(--color-secondary) 5%, transparent),
    var(--color-secondary)
  );
}

/* ---- Branded loading indicator -----------------------------------------
   A thin primary-colored progress line instead of a spinner. The element
   carries .htmx-indicator, so htmx fades it in during requests. */
.htmx-indicator {
  opacity: 0;
  transition: opacity 200ms ease-in;
}
.progress-line {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  overflow: hidden;
  pointer-events: none;
  transition: opacity 200ms ease;
}
.progress-line::after {
  content: "";
  position: absolute;
  inset: 0;
  width: 40%;
  border-radius: 2px;
  background: var(--color-primary);
  animation: progress-sweep 1.1s var(--ease-out-soft) infinite;
}
@keyframes progress-sweep {
  from {
    transform: translateX(-110%);
  }
  to {
    transform: translateX(360%);
  }
}

/* ---- Cards --------------------------------------------------------------
   Content cards lift very slightly on hover, matching the console. */
.card.border {
  position: relative;
  transition:
    box-shadow 200ms var(--ease-out-soft),
    border-color 200ms var(--ease-out-soft);
}
.card.border:hover {
  box-shadow: 0 2px 10px -4px
    color-mix(in oklab, var(--color-secondary) 24%, transparent);
  border-color: color-mix(
    in oklab,
    var(--color-secondary) 24%,
    var(--color-base-300)
  );
}

/* Brand hairline riding each card's top edge, covering half the card
   width; brightens on hover for pop (the console's .ov-tile::after) */
.card.border::after {
  content: "";
  position: absolute;
  top: -1px;
  left: 0.9rem;
  width: 50%;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(
    90deg,
    var(--color-secondary),
    color-mix(in oklch, var(--color-secondary) 5%, transparent)
  );
  opacity: 0.55;
  transition: opacity 150ms ease;
}
.card.border:hover::after {
  opacity: 1;
}

/* ---- Field focus --------------------------------------------------------
   Focused fields glow softly in the brand color. */
.input,
.select,
.textarea,
.file-input {
  transition:
    border-color 200ms ease,
    box-shadow 200ms ease;
}
.input:focus-within,
.select:focus-within,
.textarea:focus-within,
.file-input:focus-within {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px
    color-mix(in oklab, var(--color-primary) 15%, transparent);
}

/* Visible keyboard focus everywhere, in the brand color */
:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* Skip link: visually hidden until it receives keyboard focus. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0.5rem;
  z-index: 200;
}
.skip-link:focus-visible {
  left: 0.5rem;
  padding: 0.4rem 0.8rem;
  border-radius: var(--radius-field);
  background: var(--color-primary);
  color: var(--color-primary-content);
  font-size: 0.85rem;
}

/* The theme toggle checkbox stays in the tab order. daisyui's swap hides
   the input (visibility: hidden), which also removes it from keyboard
   focus; keep it visible but transparent, stretched over the button so
   its focus ring wraps the control */
.swap input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  visibility: visible;
  cursor: pointer;
}

/* Table headers: daisyui's default th color fails AA on the light theme;
   75% base-content passes (same fix as the management console) */
.table thead th {
  color: color-mix(in oklab, var(--color-base-content) 75%, transparent);
}

/* ---- Action navigation -----------------------------------------------------
   The active action is SOLID primary (the console active-selection
   convention), overriding daisyui's neutral menu-active. */
#action-nav .menu a.menu-active {
  background: var(--color-primary);
  color: var(--color-primary-content);
  font-weight: 600;
}

/* ---- Searchable select ----------------------------------------------------
   Option states for the combobox (searchable-select in actions.js). The
   keyboard-active option is solid primary (the console active-selection
   convention); the currently chosen option is marked with a tinted
   background. */
.ss-option:hover {
  background: color-mix(in oklab, var(--color-base-content) 8%, transparent);
}
.ss-option[aria-selected="true"] {
  background: color-mix(in oklab, var(--color-primary) 15%, transparent);
  font-weight: 500;
}
.ss-option.ss-active,
.ss-option.ss-active:hover,
.ss-option.ss-active[aria-selected="true"] {
  background: var(--color-primary);
  color: var(--color-primary-content);
}

/* ---- Section headings ----------------------------------------------------
   Small uppercase brand headings for the output sections, matching the
   console sidebar group headings. */
.section-heading {
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--or-accent-text);
}

/* ---- HTMX swap polish ---------------------------------------------------
   Swapped-in results settle with a soft fade/slide. */
@keyframes fade-slide-in {
  from {
    opacity: 0.4;
    transform: translateY(3px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
.htmx-settling {
  animation: fade-slide-in 250ms var(--ease-out-soft);
}

#ActionMessage {
  transition: filter 80ms ease-in-out;
}
#ActionMessage.htmx-swapping {
  filter: blur(5px);
}

/* ---- Sidebar -------------------------------------------------------------
   Reserve the docked sidebar column up front so progressively streamed
   pages do not shift when the DOM-last sidebar parses in (the console's
   layout stability fix). */
@media (min-width: 48rem) {
  .drawer.md\:drawer-open {
    grid-template-columns: 15rem auto;
    background: linear-gradient(
      to right,
      var(--color-base-100) calc(15rem - 1px),
      var(--color-base-300) calc(15rem - 1px),
      var(--color-base-300) 15rem,
      transparent 15rem
    );
  }
}

/* A small moment of delight on the brand mark, as in the console */
.logo-mark {
  transition: transform 250ms var(--ease-out-soft);
}
.logo-mark:hover {
  transform: scale(1.03);
}

/* ---- Tooltips -----------------------------------------------------------
   Cap bubble width so long descriptions stay readable; narrower on small
   screens where a wide bubble would run off the viewport. */
.tooltip:before {
  max-width: 18rem;
}
@media (max-width: 48rem) {
  .tooltip:before {
    max-width: 10rem;
  }
}

/* ---- Accessibility ------------------------------------------------------
   All motion is removed for users who prefer reduced motion. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
