/* ============================================================
 * imjustdex.com — plates.css
 * The archive grid: plate grid, plate variants, identity plate,
 * image plates, ghost teaser plate.
 *
 * Loaded on index.html only.
 * ============================================================ */

/* ── Plate grid ────────────────────────────────────────────── */

.plates {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--grid-gap);
  align-items: stretch;
}

/* ── Article wrapper ────────────────────────────────────────
 * Essay plates are wrapped in <article> for landmark semantics.
 * display: contents lets the grid see through to the .plate
 * child so grid-column spans still work. The <article> adds
 * meaning for screen readers without affecting layout.
 * -------------------------------------------------------- */

.plates > article {
  display: contents;
}

/* ── Plate base ─────────────────────────────────────────────
 * A plate is the base archive card. It can render as either:
 *   • <article><a class="plate" href=…>…</a></article> — essay cards (interactive)
 *   • <div class="plate">   — identity plate (static, not an article)
 *   • <article class="plate"> — ghost teaser (upcoming content)
 * The whole card is the single focusable/clickable element.
 * No overlay links. One focus ring per card.
 * -------------------------------------------------------- */

.plate {
  position: relative;
  min-height: var(--tile-min);
  border: var(--border-weight-content) solid var(--border);
  background: var(--panel);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
  isolation: isolate;
  color: inherit;
  text-decoration: none;
  transition: border-color var(--motion-fast) var(--ease-default);
}

/* Hover + focus only apply to interactive plates (<a class="plate">).
   Native <a> cursor already renders as pointer — no redundant rule. */
a.plate:hover {
  border-color: var(--accent);
}

a.plate:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: -5px;
}

/* ── Plate body ────────────────────────────────────────────── */

.plate-body {
  padding: var(--space-md) var(--space-md) var(--space-sm);
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  flex: 1 1 auto;
  min-height: 0;
  position: relative;
  z-index: 2;
}

/* ── Plate typography ──────────────────────────────────────── */

.plate-title,
.identity-name,
.identity-tagline {
  margin: 0;
  text-transform: uppercase;
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
  font-family: var(--display);
  font-weight: var(--weight-regular);
  word-break: break-word;
  text-wrap: balance;
}

.plate-title {
  font-size: var(--text-plate);
}

.plate-title.med {
  font-size: var(--text-plate-med);
}

.plate-title.lg {
  font-size: var(--text-plate-lg);
}

.plate-title.inverse {
  color: var(--plate-overlay-ink);
  /* Rendering shadow — raw rgba is intentional (not a semantic color). */
  text-shadow: 0 2px 0 rgba(0, 0, 0, .45);
}

html.dark-mode .plate-title.inverse {
  color: var(--plate-overlay-ink);
}

/* ── Meta rail ─────────────────────────────────────────────── */

.meta-rail {
  position: relative;
  z-index: 2;
  align-self: flex-start;
  flex-shrink: 0;
  margin: auto 0 0;
  /* Phase 6 exception — 7px top / 6px bottom = 1px optical pull up,
     centering uppercase meta label inside the badge. Sides at
     --space-xs (8) to keep the badge tight — 10→8 snap, not 10→12,
     preserving the compact meta-rail proportions. */
  padding: 7px var(--space-xs) 6px;
  background: var(--meta-bg);
  color: var(--meta-ink);
  border-top: var(--border-weight-chrome) solid var(--border);
  border-right: var(--border-weight-chrome) solid var(--border);
  font-size: var(--text-citation);
  letter-spacing: var(--track-badge);
  text-transform: uppercase;
  font-weight: var(--weight-bold);
  /* Phase 5 exception — line-height: 1 is tuned for the meta rail's
     tight badge proportions; not part of the --lh-* ladder. */
  line-height: 1;
  white-space: nowrap;
}

/* ── Plate size variants ───────────────────────────────────── */

.plate-feature {
  grid-column: span 5;
  min-height: 346px;
}

.plate-secondary {
  grid-column: span 3;
  min-height: 230px;
}

.plate-wide {
  grid-column: span 5;
  min-height: 230px;
}

.plate-banner {
  grid-column: span 4;
  min-height: 230px;
}

.plate-full {
  grid-column: span 8;
  min-height: 230px;
}

/* ── Image plates ──────────────────────────────────────────── */

.plate-image .plate-body {
  justify-content: flex-end;
  padding: var(--space-md);
}

.plate-image .plate-title {
  color: var(--plate-overlay-ink);
  /* Rendering shadow — raw rgba is intentional (not a semantic color). */
  text-shadow: 0 2px 0 rgba(0, 0, 0, .45);
}

.plate-image .meta-rail {
  color: var(--plate-image-meta-ink);
  background: var(--plate-image-meta-bg);
  border-color: var(--plate-image-meta-border);
}

.plate-image::before {
  content: "";
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  filter: grayscale(1) contrast(1.15);
  z-index: 0;
  transform: scale(1.02);
}

.plate-image::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, .78),
    rgba(0, 0, 0, .08) 55%,
    rgba(0, 0, 0, .14)
  );
  z-index: 1;
}

/* Image plates stay dark in both modes — no inversion.
   The dark ambient + dark plate maintains editorial consistency;
   inverting to light fragments the visual field. */

/* ── Image textures ────────────────────────────────────────── */

.img-concrete::before {
  background-image:
    linear-gradient(135deg, rgba(255, 255, 255, .07), rgba(0, 0, 0, .25)),
    radial-gradient(circle at 24% 22%, rgba(255, 255, 255, .18), transparent 20%),
    linear-gradient(180deg, #c7c7c7 0 18%, #8b8b8b 18% 28%, #5e5e5e 28% 45%, #2e2e2e 45% 100%);
}

.img-noise::before {
  background-image:
    linear-gradient(90deg, rgba(255, 0, 90, .18), transparent 18%, transparent 82%, rgba(0, 225, 255, .14)),
    repeating-linear-gradient(180deg, rgba(255, 255, 255, .1) 0 2px, rgba(0, 0, 0, 0) 2px 6px),
    linear-gradient(135deg, #222, #000 44%, #444 58%, #111 100%);
}

.img-lines::before {
  background-image:
    linear-gradient(135deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, 0)),
    repeating-linear-gradient(63deg, #d7d7d7 0 2px, transparent 2px 22px),
    linear-gradient(180deg, #9b9b9b, #4d4d4d 72%, #141414);
}

/* ── Identity plate ────────────────────────────────────────── */

.identity-plate {
  grid-column: span 4;
  min-height: 346px;
  cursor: default;
  background: var(--identity-plate-bg);
  color: var(--identity-plate-ink);
}

.identity-plate:hover {
  border-color: var(--border);
}

.identity-plate .plate-body {
  /* 22→24 side snap is intentional — 2px wider breathing room
     on the identity plate, well inside perception threshold at
     346px min-height. */
  padding: var(--space-lg) var(--space-lg) var(--space-md);
  gap: 0;
}

.identity-name {
  font-size: var(--text-identity);
  max-width: 7ch;
  margin-bottom: var(--space-hairline);
  /* Phase 5 exception — .82 is a tighter ratio than --lh-display (.86),
     tuned for the identity name's max 7ch width. */
  line-height: .82;
}

.identity-tagline {
  font-size: var(--text-tagline);
  max-width: 14ch;
  /* Phase 5 exception — .9 is a tuned ratio for the tagline's
     14ch width constraint, between --lh-display and --lh-tight. */
  line-height: .9;
  letter-spacing: var(--track-title);
  margin-top: var(--space-xs);
  color: var(--accent);
  opacity: .85;
}

.identity-sub {
  display: inline-block;
  margin-bottom: var(--space-xs);
  /* Phase 6 exception — identity-sub is a micro-badge sitting below
     the spacing scale floor. 5/7/4 preserves the tuned proportions:
     5 top > 4 bottom = 1px optical pull up, 7 horizontal is equally
     off-scale but tuned to the 3-letter label width. */
  padding: 5px 7px 4px;
  border: var(--border-weight-chrome) solid var(--identity-plate-ink);
  background: var(--identity-plate-ink);
  color: var(--identity-plate-bg);
  text-transform: uppercase;
  letter-spacing: var(--track-badge);
  font-weight: var(--weight-bold);
  font-size: var(--text-label);
}

.identity-plate .meta-rail {
  background: transparent;
  color: var(--identity-plate-ink);
  opacity: .45;
  border-top: 1px solid var(--identity-plate-ink);
  border-right: none;
  font-size: var(--text-micro);
  letter-spacing: var(--track-teaser);
  font-weight: var(--weight-bold);
}

/* Identity plate stays dark in dark mode — matches the editorial
   signature from light mode and prevents a lone white island in
   a field of dark plates. (The scoped --accent override that used
   to live here was removed in Phase 4.1 when --accent unified to
   #c00 across both modes — no longer needed.) */
html.dark-mode .identity-plate {
  background: var(--identity-plate-bg);
  color: var(--identity-plate-ink);
  border-color: var(--identity-plate-bg);
}

html.dark-mode .identity-sub {
  background: var(--identity-plate-ink);
  color: var(--identity-plate-bg);
  border-color: var(--identity-plate-ink);
}

html.dark-mode .identity-plate .meta-rail {
  color: var(--identity-plate-ink);
  border-top-color: var(--identity-plate-ink);
}

/* ── Ghost plate (teaser) ──────────────────────────────────── */

.plate-ghost {
  grid-column: span 5;
  min-height: 346px;
  background: transparent;
  border: var(--border-weight-content) dashed var(--border);
  cursor: default;
}

.plate-ghost:hover {
  border-color: var(--border);
}

.plate-ghost .plate-body {
  justify-content: center;
  align-items: flex-start;
  /* 28→32 top/bottom, 20→24 sides. Teaser plate, not load-bearing,
     4px drift is imperceptible at 346px min-height. */
  padding: var(--space-xl) var(--space-lg);
}

.plate-ghost .plate-title {
  color: var(--ink);
  /* .42 in light mode clears WCAG AA large-text (3.1:1 on #f4f4f1).
     Dark mode (.35) already passes (3.7:1 on #060606) — no change needed. */
  opacity: .42;
}

html.dark-mode .plate-ghost .plate-title {
  opacity: .35;
}

.plate-ghost .teaser-rule {
  width: 40px; /* intrinsic rule width, scope-excluded */
  height: 2px;
  background: var(--ink);
  opacity: .15;
  margin: var(--space-md) 0 var(--space-sm);
}

.plate-ghost .teaser-date {
  font-family: var(--body);
  font-size: var(--text-citation);
  font-weight: var(--weight-bold);
  letter-spacing: var(--track-teaser);
  text-transform: uppercase;
  color: var(--ink);
  opacity: .3;
}

.plate-ghost .meta-rail {
  background: transparent;
  color: var(--ink);
  opacity: .25;
  border-top: var(--border-weight-chrome) dashed var(--border);
  border-right: none;
}

/* ── Responsive ────────────────────────────────────────────── */

@media (max-width: 1120px) {
  .plates {
    grid-template-columns: repeat(8, 1fr);
  }

  .identity-plate {
    grid-column: span 4;
  }

  .plate-feature,
  .plate-ghost {
    grid-column: span 4;
  }

  .plate-secondary,
  .plate-banner {
    grid-column: span 4;
  }

  .plate-wide {
    grid-column: span 8;
  }

  .plate-full {
    grid-column: span 8;
  }
}

@media (max-width: 760px) {
  .plates {
    grid-template-columns: 1fr;
  }

  .identity-plate,
  .plate-feature,
  .plate-secondary,
  .plate-wide,
  .plate-full,
  .plate-banner,
  .plate-ghost {
    grid-column: span 1;
    min-height: 210px; /* intrinsic mobile tile geometry, scope-excluded */
  }

  .plate-title.lg {
    max-width: 100%;
  }
}

/* ── Print ─────────────────────────────────────────────────── */

@media print {
  .plate {
    border-color: #000 !important;
    break-inside: avoid;
  }
}
