@import "tailwindcss" source(none);
@import "phoenix-colocated/tarakan/colocated.css";
@source "../css";
@source "../js";
@source "../../lib/tarakan_web";
@source "../../_build/dev/phoenix-colocated/tarakan/*/";

@plugin "../vendor/heroicons";

@custom-variant phx-click-loading (.phx-click-loading&, .phx-click-loading &);
@custom-variant phx-submit-loading (.phx-submit-loading&, .phx-submit-loading &);
@custom-variant phx-change-loading (.phx-change-loading&, .phx-change-loading &);

[data-phx-session],
[data-phx-teleported-src] {
  display: contents;
}

/* Tailwind's preflight leaves native buttons on the default arrow cursor.
   Make the interaction contract consistent without repeating cursor utilities
   on every component and LiveView action. */
@layer base {
  html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
  }

  body {
    overflow-x: clip;
  }

  /* Prefer larger tap targets on coarse pointers without changing desktop. */
  @media (pointer: coarse) {
    button:not(:disabled),
    a,
    summary,
    [role="button"] {
      touch-action: manipulation;
    }
  }

  button:not(:disabled),
  input:is([type="button"], [type="submit"], [type="reset"]):not(:disabled) {
    cursor: pointer;
  }

  button:disabled,
  input:is([type="button"], [type="submit"], [type="reset"]):disabled {
    cursor: not-allowed;
  }
}

/* Chakra Petch (400/500/700), latin subset, vendored in priv/static/fonts */
@font-face {
  font-family: "Chakra Petch";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/chakra-petch-latin-400.woff2") format("woff2");
}

@font-face {
  font-family: "Chakra Petch";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/chakra-petch-latin-500.woff2") format("woff2");
}

@font-face {
  font-family: "Chakra Petch";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/chakra-petch-latin-700.woff2") format("woff2");
}

/* Tarakan color tokens.

   Dark (flagship): pure void black, hard white type, signal red for findings
   and primary actions, amber for secondary callouts. Borders stay cold grey so
   red only hits where it means something (findings, CTAs, live pulse).
   Light: clinical paper, black ink, the same pure red under control. */
:root {
  --ground: #f4f4f4;
  --panel: #ebebeb;
  --ink: #0a0a0a;
  --ink-muted: #444444;
  /* --ink-faint carries real telemetry (SHAs, timestamps, run counts) at 10-11px,
     so it has to clear WCAG AA against BOTH --ground and --panel, not just --ground.
     #666 = 5.2:1 on ground, 4.8:1 on panel. The old #777 was 4.1:1 / 3.8:1. */
  --ink-faint: #666666;
  --rule: #cccccc;
  --strong: #111111;
  --signal: #c40018;
  --quote: #9a6b00;
  --btn: #c40018;
  --btn-fg: #ffffff;
  /* The well is the surface live values sit on. Light keeps it visually flush
     with the ground - a dark slab reads as a defect on paper - but it must be
     an opaque paint, not transparent: wire-badge hollows fill with --well and
     would otherwise expose the badge's own stroke color. Dark gets the true
     phosphor treatment: recessed slab, scanlines, glow. */
  --well: #f4f4f4;
  --well-pad: 0;
  --phosphor: #c40018;
  --glow: none;
  --glow-soft: none;
  --scan: none;
  --live-edge: var(--signal);
}

/* Dark tokens apply via OS preference, and via the manual toggle
   (data-theme). Keep the two dark blocks identical. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: #000000;
    --panel: #0a0a0a;
    --ink: #f2f2f2;
    --ink-muted: #9a9a9a;
    --ink-faint: #7d7d7d;
    --rule: #1a1a1a;
    --strong: #2e2e2e;
    --signal: #e60012;
    --quote: #ffcc00;
    --btn: #e60012;
    --btn-fg: #ffffff;
    --well: #050505;
    --well-pad: 0.75rem;
    --phosphor: #ff1a2e;
    --live-edge: transparent;
    --glow: 0 0 12px color-mix(in srgb, var(--signal) 55%, transparent);
    --glow-soft: 0 0 8px color-mix(in srgb, var(--signal) 40%, transparent);
    --scan: repeating-linear-gradient(
      0deg,
      rgb(255 255 255 / 0.03) 0 1px,
      transparent 1px 3px
    );
  }
}

:root[data-theme="dark"] {
  --ground: #000000;
  --panel: #0a0a0a;
  --ink: #f2f2f2;
  --ink-muted: #9a9a9a;
  --ink-faint: #7d7d7d;
  --rule: #1a1a1a;
  --strong: #2e2e2e;
  --signal: #e60012;
  --quote: #ffcc00;
  --btn: #e60012;
  --btn-fg: #ffffff;
  --well: #050505;
  --well-pad: 0.75rem;
  --phosphor: #ff1a2e;
  --live-edge: transparent;
  --glow: 0 0 12px color-mix(in srgb, var(--signal) 55%, transparent);
  --glow-soft: 0 0 8px color-mix(in srgb, var(--signal) 40%, transparent);
  --scan: repeating-linear-gradient(
    0deg,
    rgb(255 255 255 / 0.03) 0 1px,
    transparent 1px 3px
  );
}

:root[data-theme="light"] {
  --ground: #f4f4f4;
  --panel: #ebebeb;
  --ink: #0a0a0a;
  --ink-muted: #444444;
  --ink-faint: #666666;
  --rule: #cccccc;
  --strong: #111111;
  --signal: #c40018;
  --quote: #9a6b00;
  --btn: #c40018;
  --btn-fg: #ffffff;
  --well: #f4f4f4;
  --well-pad: 0;
  --phosphor: #c40018;
  --glow: none;
  --glow-soft: none;
  --scan: none;
  --live-edge: var(--signal);
}

@theme inline {
  --color-ground: var(--ground);
  --color-panel: var(--panel);
  --color-ink: var(--ink);
  --color-ink-muted: var(--ink-muted);
  --color-ink-faint: var(--ink-faint);
  --color-rule: var(--rule);
  --color-strong: var(--strong);
  --color-signal: var(--signal);
  --color-quote: var(--quote);
  --color-btn: var(--btn);
  --color-btn-fg: var(--btn-fg);
  --color-well: var(--well);
  --color-phosphor: var(--phosphor);
  --font-display: "Chakra Petch", "Arial", "Helvetica Neue", sans-serif;
}

@utility clip-notch {
  /* Filled CTAs only (bg-btn etc.). Clip alone - solid fill defines the edge.
     Outline badges must use .wire-badge instead (border + clip-path eats strokes). */
  clip-path: polygon(
    0 0,
    calc(100% - 0.5rem) 0,
    100% 0.5rem,
    100% 100%,
    0.5rem 100%,
    0 calc(100% - 0.5rem)
  );
}

@utility clip-notch-sm {
  /* Filled small controls only. Outline badges: use .wire-badge. */
  clip-path: polygon(0 0, calc(100% - 5px) 0, 100% 5px, 100% 100%, 0 100%);
}

/* The newest wire entry sits on the well and reads in phosphor - the visible
   proof that the record is live. Scanlines are part of the well surface and
   disappear with it in light. Unlayered so it wins over utilities. */
#activity-wire {
  --wire-badge-fill: var(--ground);
}

/* Every row reserves the edge so live and stale rows stay aligned; only the
   live row paints it. In dark --live-edge is transparent because the well slab
   and the glow already say "live"; in light they both flatten to nothing, so
   the red edge is the only surface cue there is. */
#activity-wire article,
#shoutbox-messages article {
  border-left: 2px solid transparent;
}

#activity-wire article:first-of-type {
  background-color: var(--well);
  background-image: var(--scan);
  border-left-color: var(--live-edge);
  /* Hollow badge interiors must match the well, not the page ground. */
  --wire-badge-fill: var(--well);
}

#activity-wire article:first-of-type :is(span, time, a) {
  color: var(--phosphor);
  text-shadow: var(--glow-soft);
}

#activity-wire article:first-of-type .wire-badge {
  text-shadow: none;
}

/* The newest shout gets the same live treatment as the wire's newest entry.
   The log reads chronologically, so the newest message is the LAST article.
   Only the provenance line (handle + time) glows - shout bodies are user
   prose, not telemetry, and stay in ink. */
#shoutbox-messages article:last-of-type {
  background-color: var(--well);
  background-image: var(--scan);
  border-left-color: var(--live-edge);
}

#shoutbox-messages article:last-of-type :is(time, a) {
  color: var(--phosphor);
  text-shadow: var(--glow-soft);
}

/* Default hole colour for outline notched badges. Override on non-ground
   surfaces (e.g. #activity-wire article:first-of-type sets --well). */
:root {
  --wire-badge-fill: var(--ground);
}

.bg-panel {
  --wire-badge-fill: var(--panel);
}

/* Notched badge with a continuous stroke (top + diagonal included).
   Never use border + clip-path for outlines - clip-path eats the stroke.
   Shell = currentColor; hole = --wire-badge-fill; label above. */
.wire-badge {
  --wire-notch: 5px;
  --wire-stroke: 2px;
  position: relative;
  display: inline-flex;
  align-items: center;
  border: none !important;
  background-color: currentColor;
  clip-path: polygon(
    0 0,
    calc(100% - var(--wire-notch)) 0,
    100% var(--wire-notch),
    100% 100%,
    0 100%
  );
  padding: var(--wire-stroke);
  isolation: isolate;
}

.wire-badge::before {
  content: "";
  position: absolute;
  inset: var(--wire-stroke);
  z-index: 0;
  pointer-events: none;
  background: var(--wire-badge-fill, var(--ground));
  clip-path: polygon(
    0 0,
    calc(100% - max(0px, var(--wire-notch) - var(--wire-stroke))) 0,
    100% max(0px, var(--wire-notch) - var(--wire-stroke)),
    100% 100%,
    0 100%
  );
}

.wire-badge-label {
  position: relative;
  z-index: 1;
  display: inline-block;
  padding-inline: 0.375rem;
  padding-block: 0.125rem;
  color: inherit;
  line-height: 1.25;
}

/* Solid filled notched badges: slab only, no hollow. */
.wire-badge.bg-ink {
  background-color: var(--ink) !important;
  color: var(--ground);
}

.wire-badge.bg-signal {
  background-color: var(--signal) !important;
  color: var(--ground);
}

.wire-badge.bg-btn {
  background-color: var(--btn) !important;
  color: var(--btn-fg);
}

.wire-badge.bg-ink::before,
.wire-badge.bg-signal::before,
.wire-badge.bg-btn::before {
  display: none;
}

.wire-badge.bg-ink .wire-badge-label,
.wire-badge.bg-signal .wire-badge-label {
  color: var(--ground);
}

.wire-badge.bg-btn .wire-badge-label {
  color: var(--btn-fg);
}



/* Theme toggle: the pressed appearance is derived from the same source of
   truth as the colours themselves - the `data-theme` attribute on <html> -
   rather than from `aria-pressed`, which JavaScript can only set after the
   page has already painted. The server has no idea which theme a visitor
   chose, so it renders every button unpressed; without this the toggle
   visibly snapped to the right option a moment after load.

   Absent attribute means "follow the OS", which is the default, so that case
   needs no script at all. `aria-pressed` is still synced in JS because screen
   readers are unaffected by a paint-time flash. */
:root:not([data-theme]) [data-theme-option="system"],
:root[data-theme="light"] [data-theme-option="light"],
:root[data-theme="dark"] [data-theme-option="dark"] {
  background-color: var(--panel);
  color: var(--ink);
}
