/* Aegis Pulse — minimal custom styles on top of DaisyUI */

/* Alpine x-cloak — hide elements until Alpine initializes them, prevents
   flash-of-unstyled content when htmx swaps partials in. */
[x-cloak] { display: none !important; }

/* Kill all DaisyUI shadows — Overseer uses flat cards with borders only */
.card, .stat, [class*="bg-base-300"], [class*="bg-aegis-card"] {
  box-shadow: none !important;
}

/* Dark-scheme native controls — tells the browser to render the native date
   picker popup, scrollbars, and form control internals in dark mode.
   `accent-color` tints selected dates/checkboxes/radios with the Aegis teal
   so the native picker matches the rest of the UI. */
:root {
  color-scheme: dark;
  accent-color: #17CCBF; /* aegis-teal */
}

/* Hide the default browser calendar icon on date inputs so the input itself
   matches our other form fields. Users still click the input to open the
   native picker — the icon was the only tell that the picker was native. */
input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(0.7); /* makes the icon visible on dark backgrounds */
  cursor: pointer;
  opacity: 0.5;
}
input[type="date"]::-webkit-calendar-picker-indicator:hover {
  opacity: 1;
}

/* Flatpickr theme overrides — match the Aegis palette.
   The defaults are light and blue; we want dark + teal, matching cards
   elsewhere in the app. Selectors mirror flatpickr's own structure — we
   only override color / border / background and keep the layout intact. */
.flatpickr-calendar {
  background: #111418;                 /* aegis-card */
  border: 1px solid #272C36;           /* aegis-border */
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  border-radius: 0.5rem;
  color: #EEF1F4;                      /* aegis-text */
}
.flatpickr-calendar.arrowTop::before,
.flatpickr-calendar.arrowBottom::before { border-bottom-color: #272C36; }
.flatpickr-calendar.arrowTop::after    { border-bottom-color: #111418; }
.flatpickr-calendar.arrowBottom::after { border-top-color:    #111418; }

.flatpickr-months,
.flatpickr-months .flatpickr-month {
  background: transparent;
  color: #EEF1F4;
  border-bottom: 1px solid #272C36;
}
.flatpickr-current-month .flatpickr-monthDropdown-months,
.flatpickr-current-month input.cur-year {
  color: #EEF1F4;
  background: transparent;
}
.flatpickr-current-month .flatpickr-monthDropdown-months:hover { background: rgba(23, 204, 191, 0.1); }
.flatpickr-monthDropdown-month                                 { background: #111418; color: #EEF1F4; }

.flatpickr-prev-month, .flatpickr-next-month            { fill: #7E8A9A; }
.flatpickr-prev-month:hover, .flatpickr-next-month:hover { fill: #17CCBF; }

.flatpickr-weekdays                { background: transparent; }
.flatpickr-weekday                 { color: #7E8A9A !important; background: transparent !important; }

.flatpickr-day {
  color: #EEF1F4;
  border-radius: 0.25rem;
}
.flatpickr-day:hover,
.flatpickr-day:focus {
  background: rgba(23, 204, 191, 0.1);   /* aegis-teal/10 */
  border-color: transparent;
  color: #EEF1F4;
}
.flatpickr-day.today {
  border-color: #17CCBF;                 /* aegis-teal */
}
.flatpickr-day.today:hover {
  background: rgba(23, 204, 191, 0.2);
  color: #EEF1F4;
}
.flatpickr-day.selected,
.flatpickr-day.selected:hover,
.flatpickr-day.selected:focus {
  background: #17CCBF;                   /* aegis-teal */
  border-color: #17CCBF;
  color: #0B0F14;                        /* dark text on teal */
}
.flatpickr-day.prevMonthDay,
.flatpickr-day.nextMonthDay {
  color: rgba(126, 138, 154, 0.5);       /* muted */
}
.flatpickr-day.disabled,
.flatpickr-day.disabled:hover {
  color: rgba(126, 138, 154, 0.3);
}

.numInputWrapper span.arrowUp::after   { border-bottom-color: #7E8A9A; }
.numInputWrapper span.arrowDown::after { border-top-color:    #7E8A9A; }
.numInputWrapper:hover                 { background: rgba(23, 204, 191, 0.05); }

/* Custom <select> chevron. Native carets sit too close to the right edge
   on the dark-themed selects we use across the app; ``.pulse-select`` pairs
   with Tailwind's ``appearance-none`` and ``pr-10`` to swap the native
   arrow for a hand-rolled SVG with breathing room. */
.pulse-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%237E8A9A' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 8l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 1rem 1rem;
}
.pulse-select:hover,
.pulse-select:focus {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%2317CCBF' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 8l4 4 4-4'/%3E%3C/svg%3E");
}

/* Pulse loader — EKG scanline overlay used by long-running submits.
   The track is a static, faint path; the beam shares the same path but
   uses ``stroke-dasharray`` + an animated ``stroke-dashoffset`` so a
   single teal segment appears to travel from left to right, looping.
   ``prefers-reduced-motion`` users get a calm pulsing dot instead. */
.aegis-pulse-ekg {
  display: inline-block;
  color: #17CCBF;  /* aegis-teal */
}
.aegis-pulse-ekg__track {
  stroke: rgba(126, 138, 154, 0.35);  /* aegis-muted, low alpha */
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.aegis-pulse-ekg__beam {
  stroke: currentColor;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 7px rgba(23, 204, 191, 0.6));
  /* Path length ~360 viewBox units; dasharray draws a 70-unit lit
     segment trailing into a long gap so only one segment is visible
     at a time, looping. Slower than the 240px version so the
     larger scanline still reads as calm rather than racing. */
  stroke-dasharray: 70 360;
  stroke-dashoffset: 70;
  animation: aegis-pulse-ekg-scan 2s linear infinite;
}
@keyframes aegis-pulse-ekg-scan {
  from { stroke-dashoffset: 70; }
  to   { stroke-dashoffset: -360; }
}
@media (prefers-reduced-motion: reduce) {
  /* Drop the moving scanline: render a calm pulsing dot in its place
     so vestibular-sensitive users get the same "we're working" cue
     without the horizontal motion. */
  .aegis-pulse-ekg__beam {
    animation: none;
    stroke-dasharray: none;
    stroke-dashoffset: 0;
    opacity: 0;
  }
  .aegis-pulse-ekg::after {
    content: "";
    display: block;
    /* SVG is now 100px tall; pull the dot up by half that so it
       lands where the heartbeat spike used to draw the eye. */
    width: 18px;
    height: 18px;
    margin: -64px auto 46px auto;
    border-radius: 50%;
    background: #17CCBF;
    animation: aegis-pulse-ekg-dot 1.4s ease-in-out infinite;
  }
}
@keyframes aegis-pulse-ekg-dot {
  0%, 100% { transform: scale(1);   opacity: 1; }
  50%      { transform: scale(1.4); opacity: 0.45; }
}

/* Canvas host for charts that ship an HTML legend. The wrap becomes
   a flex column ([legend][host]) and the host claims the remaining
   space. Chart.js sizes the canvas to its parent — without this host,
   Chart.js would measure the wrap (fixed pixel height) and ignore
   the legend above, overflowing the canvas (and the x-axis labels)
   below the panel border. ``min-height: 0`` is the standard
   flex-grow trick so the host can actually shrink below its
   content's intrinsic size. */
.aegis-chart-canvas-host {
  flex: 1 1 auto;
  min-height: 0;
  position: relative;
}

/* Chart legend with hover tooltips — used by ``createAegisChart`` when
   any dataset is passed a ``description``. Replaces Chart.js's canvas
   legend with HTML buttons so we can attach hover popovers (canvas
   legend items don't support DOM tooltips). Click toggles visibility,
   matching the canvas legend's default behavior; hover surfaces the
   description so users know what each cut means before clicking. */
.aegis-chart-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  /* Wide gap so adjacent chips don't trip each other's hover
     tooltips — a small mouse drift between two close chips
     would otherwise close one popover and open the next,
     making the tooltip look like it's "jumping" between them. */
  gap: 36px;
  padding: 4px 8px 12px;
}
.aegis-chart-legend__item {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  /* Match Chart.js's canvas-legend defaults so HTML and canvas
     legends visually align across the app: 11px / system-ui. */
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 11px;
  color: #7E8A9A;  /* aegis-muted — Chart.defaults.color */
  cursor: pointer;
  background: transparent;
  border: none;
  padding: 2px 4px;
  border-radius: 3px;
}
/* Dim only the swatch + label when hidden — NOT the tooltip popover,
   which is a child of the same button. CSS ``opacity`` composes
   down the tree, so a single opacity on the button would also wash
   out the tooltip on hover (it'd look broken). Target the chrome
   pieces explicitly instead. */
/* Dim swatch + chip label of a deactivated chip. ``__pct`` is left
   out on purpose — the percent badge is governed entirely by hover/
   focus state (default hidden, visible on legend hover) and should
   behave identically for active and deactivated chips. Selection
   state and percent visibility are independent. We list each child
   individually rather than putting ``opacity: 0.4`` on the parent
   ``__item`` button because CSS opacity composes down the tree and
   would also wash out the hover-popover (the description tooltip). */
.aegis-chart-legend__item--hidden .aegis-chart-legend__swatch,
.aegis-chart-legend__item--hidden .aegis-chart-legend__chip {
  opacity: 0.4;
}
.aegis-chart-legend__item--hidden .aegis-chart-legend__chip {
  text-decoration: line-through;
}
/* Per-chip share %, hidden by default. Revealed on EVERY chip whenever
   ANY chip in the legend is hovered, OR when keyboard navigation
   focuses a chip. Uses ``:has(:focus-visible)`` rather than
   ``:focus-within`` so mouse-click focus (which sticks on the button
   after toggle) doesn't keep the percents pinned visible — focus-
   within would match on any focused child including post-click. */
.aegis-chart-legend__pct {
  color: #7E8A9A;  /* aegis-muted */
  font-variant-numeric: tabular-nums;
  margin-left: 4px;
  opacity: 0;
  transition: opacity 120ms ease;
}
.aegis-chart-legend:hover .aegis-chart-legend__pct,
.aegis-chart-legend:has(.aegis-chart-legend__item:focus-visible) .aegis-chart-legend__pct {
  opacity: 1;
}
.aegis-chart-legend__swatch {
  /* Hollow square outlined in the series color, matching the
     ``labelColor`` callback that styles Chart.js's data-point tooltip
     swatches. Keeps the legend chip and the hover tooltip visually
     consistent. Only ``border-color`` is set inline from JS (the
     per-series color); everything else is owned here. */
  width: 12px;
  height: 12px;
  background: transparent;
  border: 2px solid #7E8A9A;  /* fallback if JS doesn't set border-color */
  border-radius: 0;
  flex-shrink: 0;
}
.aegis-chart-legend__tooltip {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 30;
  width: max-content;
  max-width: 260px;
  background: #111418;  /* aegis-card */
  border: 1px solid #272C36;  /* aegis-border */
  font-size: 11px;
  line-height: 1.4;
  padding: 8px 10px;
  border-radius: 4px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 120ms ease;
  white-space: normal;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* Title row = the series name (e.g. "Public") in primary text;
   body row = the longer explanation in muted. The share % lives on
   the chip itself (see ``.aegis-chart-legend__pct``) since it shows
   for ALL chips on any chip hover. */
.aegis-chart-legend__tooltip-title {
  color: #EEF1F4;  /* aegis-text */
  font-weight: 600;
}
.aegis-chart-legend__tooltip-body {
  color: #7E8A9A;  /* aegis-muted */
}
/* Downward arrow at the bottom of the tooltip, pointing at the chip.
   Two stacked triangles: ``::after`` is the border-colored outer, ``::before``
   is the fill-colored inner shifted down 1px so the border shows through
   as a 1px outline on the arrow edges — matches the popover's border. */
.aegis-chart-legend__tooltip::after,
.aegis-chart-legend__tooltip::before {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 6px 6px 0 6px;
  border-color: transparent;
}
.aegis-chart-legend__tooltip::after {
  transform: translateX(-50%);
  border-top-color: #272C36;  /* aegis-border */
}
.aegis-chart-legend__tooltip::before {
  transform: translate(-50%, -1px);
  border-top-color: #111418;  /* aegis-card — sits on top of ::after */
  z-index: 1;
}
.aegis-chart-legend__item:hover .aegis-chart-legend__tooltip,
.aegis-chart-legend__item:focus-visible .aegis-chart-legend__tooltip {
  opacity: 1;
}

/* Chart-to-table toggle */
.aegis-insight-table {
  border-collapse: collapse;
  width: 100%;
  min-width: 360px; /* forces horizontal scroll on narrow screens */
  /* Body rows use text-sm (14px) to match the readable sizing of the
     name/value list tables; headers use text-xs (12px). */
  font-size: 14px;
  font-family: system-ui, sans-serif;
  color: #7E8A9A;
}
.aegis-insight-table thead th {
  position: sticky;
  top: 0;
  background: #111418;
  padding: 8px 16px;
  text-align: right;
  font-weight: 600;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #7E8A9A;
  border-bottom: 1px solid #272C36;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.aegis-insight-table thead th:first-child {
  text-align: left;
}
.aegis-insight-table thead th:hover {
  color: #fff;
}
.aegis-insight-table thead th.sort-active {
  color: #2DD4BF;
}
.aegis-insight-table thead th .sort-arrow {
  display: inline-block;
  margin-left: 3px;
  opacity: 0.4;
  font-style: normal;
}
.aegis-insight-table thead th.sort-active .sort-arrow {
  opacity: 1;
}
.aegis-insight-table tbody tr {
  border-bottom: 1px solid #1A1F27;
}
.aegis-insight-table tbody tr:last-child {
  border-bottom: none;
}
.aegis-insight-table tbody td {
  padding: 8px 16px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: ui-monospace, monospace;
  color: #C9D1DC;
}
.aegis-insight-table tbody td:first-child {
  text-align: left;
  font-family: system-ui, sans-serif;
  color: #7E8A9A;
}

/* Maximized chart card — the card itself goes full-screen (rather than a
   separate modal) so every binding inside it keeps working at the larger
   size. Sits above the z-40 scrim. The inner chart wrap grows to fill via
   .aegis-card-maximized [data-chart-body]. */
.aegis-card-maximized {
  position: fixed;
  inset: 1.5rem;
  z-index: 50;
  margin: 0;
  overflow: auto;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}
.aegis-card-maximized [data-chart-body] {
  height: calc(100vh - 12rem) !important;
}
.aegis-card-maximized .overflow-y-auto[x-show],
.aegis-card-maximized table {
  max-height: calc(100vh - 12rem) !important;
}
/* Even larger table type in the maximized view (base is already 14px). */
.aegis-card-maximized .aegis-insight-table {
  font-size: 16px;
}
.aegis-card-maximized .aegis-insight-table thead th {
  font-size: 13px;
  padding: 10px 18px;
}
.aegis-card-maximized .aegis-insight-table tbody td {
  padding: 10px 18px;
}

/* Sticky first column — for wide tables (e.g. downloads-by-version with
   many version columns). The Date column stays pinned-left while the
   version columns scroll horizontally. The z-index on the header's
   first cell keeps the top-left corner above both the scrolling body
   and the sticky header row. */
.aegis-sticky-first thead th:first-child,
.aegis-sticky-first tbody td:first-child {
  position: sticky;
  left: 0;
  background: #111418;
}
.aegis-sticky-first thead th:first-child {
  z-index: 2;
}
.aegis-sticky-first tbody td:first-child {
  z-index: 1;
}

/* Maximized modal — larger fonts for readability */
.aegis-chart-modal .aegis-insight-table {
  font-size: 14px;
}
.aegis-chart-modal .aegis-insight-table thead th {
  font-size: 12px;
  padding: 8px 14px;
}
.aegis-chart-modal .aegis-insight-table tbody td {
  padding: 7px 14px;
}

/* Smooth htmx transitions */
.htmx-settling {
  opacity: 0;
}
.htmx-swapping {
  opacity: 0;
  transition: opacity 100ms ease-out;
}
.htmx-added {
  opacity: 0;
}
