/* Primitive CSS — the canonical visual implementation of design/primitives/.
 *
 * Per design/LAW.md: every rule below corresponds to a primitive declared
 * in design/registry.yaml. No bespoke variants. All visual constants come
 * from design/tokens.yaml (via static/tokens.css).
 *
 * Currently implemented: modal. Other primitives land as the migration
 * progresses (K2.5).
 */

/* ============================================================
 * Modal — design/primitives/modal.jinja
 * Contract: a closed modal MUST NOT be visible. The :not([hidden])
 * guard below is the structural enforcement.
 * ============================================================ */

[data-primitive="modal"] {
  display: none;                     /* default — respect [hidden] attribute */
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
}

[data-primitive="modal"]:not([hidden]) {
  display: flex;
  align-items: center;
  justify-content: center;
  animation: modal-fade-in var(--motion-duration-base) var(--motion-ease-entrance);
}

@keyframes modal-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

[data-primitive="modal"] .modal__backdrop {
  position: absolute;
  inset: 0;
  background: var(--color-scrim);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

[data-primitive="modal"] .modal__panel {
  position: relative;
  background: var(--color-surface);
  border: 1px solid var(--color-rule);
  border-radius: var(--radii-xl);
  box-shadow: var(--shadow-modal);
  padding: var(--space-7) var(--space-8);
  width: 90%;
  max-height: 85vh;
  display: flex;
  flex-direction: column;
  color: var(--color-text);
}

[data-primitive="modal"].modal--sm .modal__panel { max-width: 360px; }
[data-primitive="modal"].modal--md .modal__panel { max-width: 520px; }
[data-primitive="modal"].modal--lg .modal__panel { max-width: 720px; }

/* Peek — centered viewport-bounded card for previewing a longer
 * surface (document, deck, sheet, controls matrix, manifest, etc.)
 * without committing to navigating to it. The user retains an "I'm
 * peeking, the source page is still there underneath" mental model.
 *
 * This is the general pattern Linear (issue quick-view), Stripe
 * (invoice preview), Vercel (deployment preview), Notion (page peek)
 * all use. It is NOT a sheet (no edge anchor) and NOT a dialog
 * (much larger, content-driven, dismissible by clicking away).
 *
 * Sizing rules (deliberately tight so consumers don't override):
 *  - width capped at 960px and never closer than 48px from each edge
 *  - height capped at 820px and never taller than 80vh
 *  - bottom corners rounded same as top (not sheet-shaped)
 *  - subtle scale-in pairs with the global opacity fade
 *
 * At ≤720px the peek collapses to a near-fullscreen sheet because
 * there's no breathing room for margins on a phone. */
[data-primitive="modal"].modal--peek .modal__panel {
  width: min(960px, calc(100vw - 96px));
  max-width: min(960px, calc(100vw - 96px));
  height: min(820px, 80vh);
  max-height: min(820px, 80vh);
  padding: 0;                              /* reader owns its own padding */
  overflow: hidden;
  align-self: center;
  animation: modal-peek-in var(--motion-duration-base) var(--motion-ease-standard);
  transform-origin: center;
}

@keyframes modal-peek-in {
  from { opacity: 0; transform: scale(0.97); }
  to   { opacity: 1; transform: scale(1); }
}

[data-primitive="modal"].modal--sheet .modal__panel {
  max-width: 100%;
  width: 100%;
  border-radius: var(--radii-lg) var(--radii-lg) 0 0;
  align-self: flex-end;
}

@media (max-width: 720px) {
  /* Peek becomes a sheet on phones — the primitive owns this
   * transition so every consumer (reader, deck preview, etc.)
   * gets the right mobile shape without thinking about it. */
  [data-primitive="modal"].modal--peek .modal__panel {
    width: 100%;
    max-width: 100%;
    height: calc(100vh - 16px);
    max-height: calc(100vh - 16px);
    align-self: flex-end;
    border-radius: var(--radii-lg) var(--radii-lg) 0 0;
  }
}

[data-primitive="modal"] .modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  margin-bottom: var(--space-5);
}

[data-primitive="modal"] .modal__title {
  margin: 0;
  font-family: var(--type-title-family);
  font-size: var(--type-title-size);
  line-height: var(--type-title-line);
  font-weight: var(--type-title-weight);
  color: var(--color-text);
}

[data-primitive="modal"] .modal__close {
  background: transparent;
  border: 1px solid var(--color-rule);
  border-radius: var(--radii-pill);
  width: 28px;
  height: 28px;
  font-size: 16px;
  line-height: 1;
  color: var(--color-text-muted);
  cursor: pointer;
  transition: color var(--motion-duration-fast) var(--motion-ease-standard);
}

[data-primitive="modal"] .modal__close:hover {
  color: var(--color-action);
}

[data-primitive="modal"] .modal__close:focus-visible {
  outline: 2px solid var(--color-action);
  outline-offset: 2px;
}

[data-primitive="modal"] .modal__body {
  overflow-y: auto;
  color: var(--color-text);
}

/* Body lock when any modal is open (set by primitives.js) */
body.modal-open {
  overflow: hidden;
}

/* ============================================================
 * Global type baseline
 * Inter for UI, Charter for reader prose, IBM Plex Mono for code.
 * ============================================================ */
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
body {
  font-family: var(--type-body-family);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
  color: var(--color-text);
  background: var(--color-bg);
}

/* ============================================================
 * Icon — Material Symbols Outlined (Google, Apache 2.0)
 * Usage: <span class="icon">search</span>
 *        <span class="icon icon-sm">visibility</span>
 *        <span class="icon icon-lg" data-filled="true">check_circle</span>
 *
 * The font is loaded in base.html via the Google Fonts CSS URL.
 * Variable axes (FILL, wght, GRAD, opsz) wire via data attributes.
 * ============================================================ */
.icon {
  font-family: 'Material Symbols Outlined', sans-serif;
  font-weight: normal;
  font-style: normal;
  font-size: 20px;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
  vertical-align: middle;
  -webkit-font-feature-settings: 'liga';
  font-feature-settings: 'liga';
  -webkit-font-smoothing: antialiased;
  font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
  user-select: none;
  flex-shrink: 0;
}

.icon-sm { font-size: 16px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20; }
.icon-md { font-size: 20px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24; }
.icon-lg { font-size: 24px; font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 28; }
.icon-xl { font-size: 32px; font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 40; }

.icon[data-filled="true"] {
  font-variation-settings: 'FILL' 1, 'wght' 500, 'GRAD' 0, 'opsz' 24;
}

/* ============================================================
 * Eyebrow — design/primitives/eyebrow.jinja
 * The canonical small uppercase letter-spaced category label.
 * All visual constants come from static/tokens.css.
 * ============================================================ */

[data-primitive="eyebrow"] {
  display: inline-block;
  font-family: var(--type-eyebrow-family);
  font-size: var(--type-eyebrow-size);
  line-height: var(--type-eyebrow-line);
  font-weight: var(--type-eyebrow-weight);
  letter-spacing: var(--type-eyebrow-tracking);
  text-transform: uppercase;
  margin: 0;
  padding: 0;
}

[data-primitive="eyebrow"][data-tone="primary"]  { color: var(--color-eyebrow); }
[data-primitive="eyebrow"][data-tone="subdued"]  { color: var(--color-eyebrow-subdued); }
[data-primitive="eyebrow"][data-tone="danger"]   { color: var(--color-red); }

/* ============================================================
 * Button — design/primitives/button.jinja
 * One canonical button primitive. Variants via data-variant.
 * ============================================================ */

[data-primitive="button"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  font-family: var(--type-button-family);
  font-size: var(--type-button-size);
  font-weight: var(--type-button-weight);
  letter-spacing: var(--type-button-tracking);
  text-transform: uppercase;
  border: 1px solid transparent;
  border-radius: var(--radii-md);
  cursor: pointer;
  text-decoration: none;
  transition: background var(--motion-duration-fast) var(--motion-ease-standard),
              border-color var(--motion-duration-fast) var(--motion-ease-standard),
              color var(--motion-duration-fast) var(--motion-ease-standard);
  user-select: none;
}

[data-primitive="button"]:focus-visible {
  outline: 2px solid var(--color-orange);
  outline-offset: 2px;
}

[data-primitive="button"]:disabled,
[data-primitive="button"][aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Primary — orange filled */
[data-primitive="button"][data-variant="primary"] {
  background: var(--color-orange);
  color: var(--color-text-inverse);
  border-color: var(--color-orange);
}
[data-primitive="button"][data-variant="primary"]:hover:not(:disabled) {
  background: #B53F00;
  border-color: #B53F00;
}

/* Secondary — outlined */
[data-primitive="button"][data-variant="secondary"] {
  background: transparent;
  color: var(--color-text);
  border-color: var(--color-rule);
}
[data-primitive="button"][data-variant="secondary"]:hover:not(:disabled) {
  border-color: var(--color-orange);
  color: var(--color-orange);
}

/* Ghost — no border */
[data-primitive="button"][data-variant="ghost"] {
  background: transparent;
  color: var(--color-text-muted);
  border-color: transparent;
}
[data-primitive="button"][data-variant="ghost"]:hover:not(:disabled) {
  background: var(--color-paper);
  color: var(--color-orange);
}

/* Danger — red filled */
[data-primitive="button"][data-variant="danger"] {
  background: var(--color-red);
  color: var(--color-text-inverse);
  border-color: var(--color-red);
}
[data-primitive="button"][data-variant="danger"]:hover:not(:disabled) {
  background: #8A1212;
  border-color: #8A1212;
}

/* Accessibility utility — visually hide but keep available to screen readers. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
