/* ============================================================
   Asetrix · entry stylesheet
   Order matters: tokens first, then reset, then primitives.
   Consumers reference this single file via:
     <link href="_content/Asetrix.Shared/css/app.css" rel="stylesheet" />
   ============================================================ */

@import url('./_tokens.css');
@import url('./_reset.css');
@import url('./_typography.css');
@import url('./_primitives.css');

/* ─── Blazor unhandled-error UI ─────────────────────────────────
   Hidden by default. Blazor toggles display:block via inline style
   when an uncaught component exception fires. Both marketplace and
   portal embed the same <div id="blazor-error-ui"> in their root
   layouts, so the rule lives in the shared stylesheet to avoid
   the regression where one host has it and the other does not.

   Styling matches the platform token system. The dismiss "×" is
   absolutely positioned so the body text reads cleanly. */
#blazor-error-ui {
  color-scheme: light only;
  position: fixed;
  inset: auto 0 0 0;
  z-index: var(--z-toast, 9999);
  display: none;
  padding: var(--space-3, 0.75rem) var(--space-5, 1.25rem);
  background: var(--warning-subtle, #fff7ed);
  color: var(--warning, #92400e);
  border-top: 1px solid var(--warning, #f59e0b);
  box-shadow: var(--shadow-md, 0 -4px 16px rgba(0,0,0,0.08));
  font-size: 0.95rem;
  box-sizing: border-box;
}

#blazor-error-ui .reload {
  color: inherit;
  text-decoration: underline;
  margin-left: var(--space-3, 0.75rem);
  font-weight: 600;
}

#blazor-error-ui .dismiss {
  cursor: pointer;
  position: absolute;
  right: var(--space-4, 1rem);
  top: var(--space-2, 0.5rem);
  font-size: 1.25rem;
  line-height: 1;
}

/* ============================================================
   Theme toggle — single morphing icon.

   Sun → moon transition: in light mode the SVG renders as a sun
   (rays + solid body); in dark mode the rays fade-and-shrink out
   while a "bite" circle slides into the body to carve it into a
   crescent. The bite is filled with the page background colour
   so it reads as an absence of the body, not a separate shape.

   All animation is CSS — no JS beyond the existing toggle script
   that flips data-theme on <html>.
   ============================================================ */

.theme-toggle {
    display: inline-grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border: 1px solid rgba(20, 83, 45, 0.10);
    border-radius: 10px;
    background: transparent;
    color: var(--asetrix-brand, #14532D);
    cursor: pointer;
    transition: background 180ms ease, border-color 180ms ease, transform 180ms ease;
}

.theme-toggle:hover {
    background: rgba(22, 163, 74, 0.06);
    border-color: rgba(20, 83, 45, 0.18);
}

.theme-toggle:active { transform: scale(0.96); }

.theme-toggle:focus-visible {
    outline: 3px solid rgba(20, 83, 45, 0.25);
    outline-offset: 2px;
}

[data-theme="dark"] .theme-toggle {
    color: #F0F4F1;
    border-color: rgba(255, 255, 255, 0.08);
}
[data-theme="dark"] .theme-toggle:hover {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.16);
}

.theme-toggle-track {
    display: inline-block;
    width: 20px;
    height: 20px;
    line-height: 0;
}

.theme-toggle-icon {
    overflow: visible;
    transition: transform 520ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Sun rays — fade + scale out when dark */
.theme-toggle-rays {
    transition: opacity 380ms ease, transform 520ms cubic-bezier(0.34, 1.56, 0.64, 1);
    transform-origin: 12px 12px;
}
[data-theme="dark"] .theme-toggle-rays {
    opacity: 0;
    transform: scale(0.4) rotate(-90deg);
}

/* Body — the solid circle. Inherits currentColor from the button. */
.theme-toggle-body { transition: r 380ms ease; }

/* Bite — slides over the body to carve it into a crescent. The fill
   is the page background so the bite reads as an absence. */
.theme-toggle-bite {
    transform: translate(8px, -8px);
    transition: transform 520ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
[data-theme="dark"] .theme-toggle-bite {
    transform: translate(0, 0);
}

/* On dark surfaces the bite fill switches to the dark background. */
[data-theme="dark"] .theme-toggle-bite {
    fill: #0D130F;
}

@media (prefers-reduced-motion: reduce) {
    .theme-toggle-icon,
    .theme-toggle-rays,
    .theme-toggle-bite { transition: none; }
}
