/*
  render-sentry-ember.css — STUDENT sample skin: SENTRY / Ember
  ===========================================================================
  Built to the owner's own reference, panel-theme-kit-v5.html ("SENTRY — SYSTEM
  PANEL SKIN", EMBER palette), after he supplied screenshots showing an earlier
  attempt had not matched it. That attempt was based on a different card in
  six-terminals.html; this file is the SENTRY construction proper.

  THE SIGNATURE, in the reference's own words:
    "Bars run wider than the plate and sit apart from it. They are built from
     stacked hairlines at different lengths, with breaks cut through the bright
     core. The plate floats inside on a dark gap, veined with hairline cracks."

  So the frame is its OWN OBJECT — not a border on the plate. Three ideas have
  to survive the port:
    1. the bars are WIDER than the plate and DETACHED from it (a dark gap)
    2. the bar is a STACK: bright core + notch breaks + two hairlines whose
       lengths deliberately differ, so it never reads as a single drawn line
    3. the vertical posts are BROKEN, not continuous

  PORTING NOTE — why this looks different in source but identical on screen.
  The reference builds each bar from a <div class="bar"> holding four <i>
  children, which it can do because it owns its own markup. A skin cannot add
  markup, so each bar here is ONE pseudo-element carrying the same four parts as
  stacked background layers, and the angled ends come from clip-path on the
  pseudo-element itself. The glow uses filter: drop-shadow() rather than
  box-shadow, because clip-path clips a box-shadow but drop-shadow follows the
  clipped silhouette — that is the one substantive technique change, and it is
  the reason the ends still glow.

  .bu-panel has exactly two pseudo-elements, and both are spent on the bars, so
  the posts and the crackle veining ride on the panel's own background layers.
  That is why the background stack below is long: it is carrying four separate
  visual jobs at once.

  Palette: MEASURED from the reference's [data-theme="ember"] token block, not
  authored — including its deliberate note that amber sits lower in luminance
  against near-black than cyan, so muted text is lifted to hold contrast at
  phone size.

  Token law (D-S07-NS-02): --theme-* only. Complete assignment (D-TPL-TOK-02).
  Selector coverage matches render-fight-night.css 1:1 (D-S07-SKIN-02).
  STATUS: sample, pending owner approval.
  ===========================================================================
*/

:root[data-theme="sentry-ember"] {
  /* --- Surfaces — measured from the reference ember token block ----------- */
  --theme-bg-canvas: #0B0703;
  --theme-bg-surface: #221606;
  --theme-bg-frosted: #221606;
  --theme-bg-card: #2C1D08;
  --theme-x-bg-sunken: #060401;
  --theme-border-inactive: rgba(255, 180, 60, 0.28);
  --theme-border-active: #FFB43C;

  /* --- Text roles ---------------------------------------------------------
     --theme-text-muted is lifted to .74 alpha per the reference's own comment
     about amber luminance; do not "normalise" it back down to the usual .62. */
  --theme-text-main: #FDEDD3;
  --theme-x-text-secondary: rgba(253, 237, 211, 0.86);
  --theme-text-muted: rgba(253, 237, 211, 0.74);
  --theme-x-text-inverse: #0B0703;
  --theme-x-text-disabled: rgba(253, 237, 211, 0.38);

  /* --- Interactive states ------------------------------------------------- */
  --theme-accent-primary: #FFB43C;
  --theme-accent-secondary: #6B3D06;
  --theme-x-accent-hover: #FFEAC0;
  --theme-x-accent-active: #E09A2A;
  --theme-x-accent-disabled: rgba(255, 180, 60, 0.25);
  --theme-x-accent-text: #0B0703;
  --theme-x-focus-ring: #FFEAC0;

  /* --- Feedback ------------------------------------------------------------ */
  --theme-state-healthy: #9FBF5A;
  --theme-state-warning: #FFB43C;
  --theme-state-error: #FF6B4A;
  --theme-x-state-info: #FFEAC0;

  /* --- Elevation / glow ---------------------------------------------------- */
  --theme-x-elevation-1: 0 1px 2px rgba(0, 0, 0, 0.6);
  --theme-x-elevation-2: 0 26px 70px -44px #000;
  --theme-x-elevation-3: 0 0 56px -4px #FFB43C;
  --theme-accent-glow: 0 0 20px 0 rgba(255, 180, 60, 0.75);
  --theme-accent-glow-secondary: 0 0 56px -4px rgba(255, 180, 60, 0.6);
  --theme-x-glass-tint: rgba(11, 7, 3, 0.8);
  --theme-backdrop-blur: 6px;

  /* --- Type ---------------------------------------------------------------- */
  --theme-x-font-family-base: "Jost", "Inter", system-ui, sans-serif;
  --theme-x-font-size-sm: 0.875rem;
  --theme-x-font-size-base: 1rem;
  --theme-x-font-size-lg: 1.25rem;
  --theme-x-font-size-xl: 1.75rem;
  --theme-x-line-height-base: 1.5;
  --theme-x-space-unit: 0.5rem;

  /* Frame geometry — named so the three numbers that define the look are
     tunable in one place, exactly as the reference does with --bar-h /
     --frame-inset. */
  --sentry-bar-h: 14px;
  --sentry-gap: 9px;
  --sentry-overhang: 26px;
}

/* ============================================================
   THE PLATE
   Floats inside the bars on a dark gap. Carries the broken side
   posts and the crackle veining as background layers, because both
   pseudo-elements are spent on the bars.
   ============================================================ */
:root[data-theme="sentry-ember"] .bu-panel {
  position: relative;
  /* Vertical room for the detached bars to sit in without colliding with the
     next panel: bar height + the gap, top and bottom. */
  margin-top: calc(var(--sentry-bar-h) + var(--sentry-gap));
  margin-bottom: calc(var(--sentry-bar-h) + var(--sentry-gap));
  border: none;
  border-radius: 0;
  color: var(--theme-text-main);

  background-image:
    /* 1. crackle veining — branching hairlines, very low contrast. Art ported
          verbatim from the reference's .plate::before. Stroke opacity is .12,
          not the source's .55, because the reference ALSO puts opacity:.17 on
          the pseudo-element carrying it (~.09 effective). A background layer
          has no per-layer opacity, so the multiplication is folded into the
          stroke instead — without this the veins read ~3x too strong. */
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 300'><g fill='none' stroke='%23ffffff' stroke-width='.7' opacity='.12'><path d='M0 58 L37 70 L69 52 L106 79 L136 62 L174 87 L213 69 L248 96 L300 76'/><path d='M69 52 L79 23 L97 7'/><path d='M136 62 L149 32'/><path d='M174 87 L188 119 L174 154'/><path d='M0 182 L34 168 L64 193 L96 174 L133 201 L166 183 L198 211 L236 189 L300 215'/><path d='M96 174 L86 144'/><path d='M198 211 L213 243 L199 281'/><path d='M34 168 L19 136'/><path d='M236 189 L254 161 L283 151'/><path d='M248 96 L266 126 L300 137'/><path d='M106 79 L118 104 L99 131'/></g></svg>"),
    /* 2 + 3. broken vertical posts, left and right — deliberately gapped, not
          continuous, per the reference's .post gradient stops. */
    linear-gradient(180deg,
      var(--theme-accent-primary) 0 22%, transparent 22% 34%,
      var(--theme-accent-primary) 34% 40%, transparent 40% 60%,
      var(--theme-accent-primary) 60% 66%, transparent 66% 78%,
      var(--theme-accent-primary) 78% 100%),
    linear-gradient(180deg,
      var(--theme-accent-primary) 0 22%, transparent 22% 34%,
      var(--theme-accent-primary) 34% 40%, transparent 40% 60%,
      var(--theme-accent-primary) 60% 66%, transparent 66% 78%,
      var(--theme-accent-primary) 78% 100%),
    /* 4. plate fill — top sheen over a deep raking gradient. */
    linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0) 55%),
    linear-gradient(170deg, #1B1105, var(--theme-bg-canvas));

  background-repeat: repeat, no-repeat, no-repeat, no-repeat, no-repeat;
  background-position: 0 0, left center, right center, 0 0, 0 0;
  background-size: 300px 300px, 2px 86%, 2px 86%, 100% 100%, 100% 100%;

  box-shadow:
    inset 0 0 0 1px rgba(255, 180, 60, 0.42),
    inset 0 0 60px -26px var(--theme-accent-primary),
    var(--theme-x-elevation-2);
}

/* ============================================================
   THE BARS
   One pseudo-element each, carrying core + notches + two hairlines
   as stacked background layers. Wider than the plate on both sides
   (--sentry-overhang) and held off it by --sentry-gap.
   ============================================================ */
:root[data-theme="sentry-ember"] .bu-panel::before,
:root[data-theme="sentry-ember"] .bu-panel::after {
  content: "";
  position: absolute;
  left: calc(var(--sentry-overhang) * -1);
  right: calc(var(--sentry-overhang) * -1);
  height: var(--sentry-bar-h);
  pointer-events: none;

  /* Angled ends, straight from the reference's .bar .core clip-path. */
  clip-path: polygon(0 0, 100% 0, calc(100% - 13px) 100%, 13px 100%);

  background-image:
    /* hairline A — top edge, 5%..82%: shorter, and offset differently from B
       so the two never line up. That mismatch is the whole trick. */
    linear-gradient(var(--theme-accent-primary), var(--theme-accent-primary)),
    /* hairline B — bottom edge, 14%..96% */
    linear-gradient(var(--theme-accent-primary), var(--theme-accent-primary)),
    /* notch breaks, cut through the core in canvas colour */
    linear-gradient(90deg,
      transparent 0 23%, var(--theme-bg-canvas) 23% 23.5%,
      transparent 23.5% 51%, var(--theme-bg-canvas) 51% 51.4%,
      transparent 51.4% 76%, var(--theme-bg-canvas) 76% 76.6%,
      transparent 76.6% 100%),
    /* the bright core */
    linear-gradient(180deg,
      var(--theme-x-accent-hover),
      var(--theme-accent-primary) 55%,
      var(--theme-accent-secondary));

  background-repeat: no-repeat;
  background-position: 5% 0, 14% 100%, 0 4px, 0 4px;
  background-size: 77% 1px, 82% 1px, 100% 8px, 100% 8px;

  /* drop-shadow, NOT box-shadow: clip-path clips a box-shadow, so the angled
     ends would go dark. drop-shadow follows the clipped silhouette. */
  filter: drop-shadow(0 0 10px rgba(255, 180, 60, 0.85));
}

:root[data-theme="sentry-ember"] .bu-panel::before {
  top: calc((var(--sentry-bar-h) + var(--sentry-gap)) * -1);
}

/* The bottom bar is the top bar mirrored, so the hairline stack reads as a
   reflection rather than a repeat — the reference does the same with
   .bar--bottom { transform: scaleY(-1) }. */
:root[data-theme="sentry-ember"] .bu-panel::after {
  bottom: calc((var(--sentry-bar-h) + var(--sentry-gap)) * -1);
  transform: scaleY(-1);
}

/* ============================================================
   TYPE + THE REST OF THE SELECTOR SET
   ============================================================ */
:root[data-theme="sentry-ember"] body {
  background-color: var(--theme-bg-canvas);
  color: var(--theme-text-main);
  font-family: var(--theme-x-font-family-base);
  /* The reference's atmosphere: deep pools of accent behind everything. */
}

:root[data-theme="sentry-ember"] h1,
:root[data-theme="sentry-ember"] h2,
:root[data-theme="sentry-ember"] h3,
:root[data-theme="sentry-ember"] h4,
:root[data-theme="sentry-ember"] h5,
:root[data-theme="sentry-ember"] h6 {
  color: var(--theme-text-main);
  font-weight: 300;
  letter-spacing: 0.01em;
}

:root[data-theme="sentry-ember"] a { color: var(--theme-accent-primary); }
:root[data-theme="sentry-ember"] p,
:root[data-theme="sentry-ember"] li { color: var(--theme-x-text-secondary); }
:root[data-theme="sentry-ember"] .bu-brick { color: var(--theme-x-text-secondary); }

:root[data-theme="sentry-ember"] .bu-rail {
  background-color: var(--theme-x-bg-sunken);
  border-bottom: 1px solid var(--theme-border-inactive);
  color: var(--theme-text-main);
}

:root[data-theme="sentry-ember"] .bu-soffit {
  border-top: 1px solid var(--theme-border-inactive);
  color: var(--theme-text-muted);
}
:root[data-theme="sentry-ember"] .bu-soffit a { color: var(--theme-text-muted); }
:root[data-theme="sentry-ember"] .bu-soffit a:hover { color: var(--theme-text-main); }

/* Controls echo the bar's angled ends at a scale that keeps the Primer's 5px
   interactive-radius accessibility cap intact. */
:root[data-theme="sentry-ember"] .bu-btn {
  background: var(--theme-accent-primary);
  border-color: var(--theme-accent-primary);
  color: var(--theme-x-accent-text);
  clip-path: polygon(0 0, 100% 0, calc(100% - 8px) 100%, 8px 100%);
}
:root[data-theme="sentry-ember"] .bu-btn:hover {
  background: var(--theme-x-accent-hover);
  border-color: var(--theme-x-accent-hover);
  filter: drop-shadow(0 0 8px rgba(255, 180, 60, 0.8));
}
:root[data-theme="sentry-ember"] .bu-btn:focus-visible {
  outline: 2px solid var(--theme-x-focus-ring);
  outline-offset: 2px;
}
:root[data-theme="sentry-ember"] .bu-btn:disabled {
  background: var(--theme-x-accent-disabled);
  border-color: var(--theme-x-accent-disabled);
  color: var(--theme-x-text-disabled);
}

:root[data-theme="sentry-ember"] .bu-btn-secondary {
  background: transparent;
  border-color: var(--theme-border-inactive);
  color: var(--theme-text-main);
}
:root[data-theme="sentry-ember"] .bu-btn-secondary:hover {
  border-color: var(--theme-border-active);
  color: var(--theme-accent-primary);
}
:root[data-theme="sentry-ember"] .bu-btn-secondary:focus-visible {
  outline: 2px solid var(--theme-x-focus-ring);
  outline-offset: 2px;
}
:root[data-theme="sentry-ember"] .bu-btn-secondary.is-active {
  border-color: var(--theme-border-active);
  background: var(--theme-accent-primary);
  color: var(--theme-x-accent-text);
}

:root[data-theme="sentry-ember"] .bu-control {
  background: var(--theme-bg-card);
  border-color: var(--theme-border-inactive);
  color: var(--theme-text-main);
}
:root[data-theme="sentry-ember"] .bu-control:hover { border-color: var(--theme-border-active); }
:root[data-theme="sentry-ember"] .bu-control:focus-visible {
  outline: 2px solid var(--theme-x-focus-ring);
  outline-offset: 2px;
}

:root[data-theme="sentry-ember"] .bu-gate { background: var(--theme-x-glass-tint); }

:root[data-theme="sentry-ember"] .bu-gauge svg .bg { stroke: var(--theme-border-inactive); }
:root[data-theme="sentry-ember"] .bu-gauge svg .fg { stroke: var(--theme-accent-primary); }

/* Segmented, like the reference's LEGIBILITY meter — a bar of lit blocks with
   dark breaks, not one continuous fill. */
:root[data-theme="sentry-ember"] .bu-progress-track {
  background-color: var(--theme-x-bg-sunken);
  background-image: repeating-linear-gradient(90deg,
    transparent 0 26px, var(--theme-bg-canvas) 26px 30px);
}

:root[data-theme="sentry-ember"] .bu-badge-tag {
  background: transparent;
  border: 1px solid var(--theme-border-inactive);
  color: var(--theme-text-main);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

:root[data-theme="sentry-ember"] .bu-status-dot { background: var(--theme-text-muted); }
:root[data-theme="sentry-ember"] .bu-status-dot.is-healthy { background: var(--theme-state-healthy); }
:root[data-theme="sentry-ember"] .bu-status-dot.is-active { background: var(--theme-state-healthy); }
:root[data-theme="sentry-ember"] .bu-status-dot.is-warning { background: var(--theme-state-warning); }
:root[data-theme="sentry-ember"] .bu-status-dot.is-alert { background: var(--theme-state-warning); }
:root[data-theme="sentry-ember"] .bu-status-dot.is-error { background: var(--theme-state-error); }
:root[data-theme="sentry-ember"] .bu-status-dot.is-neutral { background: var(--theme-text-muted); }

/* ===========================================================================
   DEPTH — the parallaxing atmosphere behind the panels
   ===========================================================================
   Owner 2026-08-23: the skins read flat because the panels had nothing to float
   in front of. The reference (panel-theme-kit.html) always had this: a `.sky`
   of stacked radial pools, drifting motes, and a mesh behind the panels.

   The parallax is pure CSS. `background-attachment: fixed` anchors a layer to
   the viewport so it does NOT move on scroll, while a `scroll` layer travels
   with the content. Stack both and they separate as the page moves —
   differential motion is parallax. No JS, no scroll listener, nothing to jank.

   Far to near: colour pools (fixed) -> fine motes (fixed) -> coarse motes
   (scroll) -> vignette (fixed). The coarse layer moving against the fixed ones
   is what the eye actually reads as depth.

   Mobile note: several mobile browsers ignore `background-attachment: fixed`
   and will render this static. That degrades to a still backdrop — no parallax,
   nothing broken — which is the right floor for a scroll effect.
   =========================================================================== */
:root[data-theme="sentry-ember"] body {
  background-color: #0B0703;
  background-image:
    /* 4. vignette — burns the edges so the centre reads deeper */
    radial-gradient(120% 90% at 50% 50%, transparent 42%, rgba(0,0,0, 0.55) 100%),
    /* 3. NEAR motes — travel with the content */
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='340' height='340' viewBox='0 0 340 340'><g fill='rgb(255,180,60)' opacity='0.55'><circle cx='44.2' cy='71.4' r='1.5'/><circle cx='159.8' cy='30.6' r='1.5'/><circle cx='268.6' cy='105.4' r='1.5'/><circle cx='95.2' cy='197.2' r='1.5'/><circle cx='210.8' cy='244.8' r='1.5'/><circle cx='309.4' cy='214.2' r='1.5'/><circle cx='23.8' cy='285.6' r='1.5'/><circle cx='187.0' cy='319.6' r='1.5'/><circle cx='125.8' cy='139.4' r='1.5'/><circle cx='244.8' cy='57.8' r='1.5'/></g></svg>"),
    /* 2. FAR motes — pinned to the viewport */
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='190' height='190' viewBox='0 0 190 190'><g fill='rgb(255,180,60)' opacity='0.55'><circle cx='24.7' cy='39.9' r='0.9'/><circle cx='89.3' cy='17.1' r='0.9'/><circle cx='150.1' cy='58.9' r='0.9'/><circle cx='53.2' cy='110.2' r='0.9'/><circle cx='117.8' cy='136.8' r='0.9'/><circle cx='172.9' cy='119.7' r='0.9'/><circle cx='13.3' cy='159.6' r='0.9'/><circle cx='104.5' cy='178.6' r='0.9'/></g></svg>"),
    /* 1. atmosphere: pools of light at infinity */
    radial-gradient(120% 80% at 50% -12%, #6B3D06 0%, transparent 56%),
    radial-gradient(80% 60% at 6% 100%, #221606 0%, transparent 62%),
    radial-gradient(70% 55% at 94% 76%, #221606 0%, transparent 64%);
  background-attachment: fixed, scroll, fixed, fixed, fixed, fixed;
  background-size: cover, 340px 340px, 190px 190px, cover, cover, cover;
  background-repeat: no-repeat, repeat, repeat, no-repeat, no-repeat, no-repeat;
  animation: bu-atmosphere-drift 90s linear infinite;
}

/* Only the near mote layer drifts; everything else is anchored. Animating just
   one layer's position keeps the parallax reading as depth rather than as the
   whole backdrop sliding. */
@keyframes bu-atmosphere-drift {
  to {
    background-position:
      center, 340px 340px, 0 0, center, center, center;
  }
}

@media (prefers-reduced-motion: reduce) {
  :root[data-theme="sentry-ember"] body { animation: none; }
}

/* The app's own preference, honoured separately from the OS query. */
:root[data-reduced-motion="true"][data-theme="sentry-ember"] body {
  animation: none;
}
