/* ==========================================================================
   poraque.seixas.dev — custom tweaks on top of Tailwind

   Tailwind does the layout work (compiled to tailwind.css, which is linked
   BEFORE this file). This file only holds the few things that are awkward to
   express as utility classes: the shared card surface, the hero dot texture,
   entrance animations, focus styling and the command blocks on /install.

   Unlike tailwind.css, this file is hand-written and needs no build step —
   edit it and reload.

   Deliberately a near-copy of calango-studio.seixas.dev/static/css/style.css, which
   is itself a near-copy of seixas.dev's. The parts unique to this product
   page are at the end, marked off. Everything above that is byte-identical
   on purpose, so the three sites keep looking like one family.
   ========================================================================== */

:root {
  --surface: #ffffff;
  --surface-border: #e2e8f0;      /* slate-200 */
  /* Bumped up from 0.055 — a dot needs more ink than a continuous line to
     read at the same visual weight, and this was asked to be more visible
     than the original line grid anyway. */
  --grid-line: rgba(15, 23, 42, 0.22);
  /* Reuses the token from assets/tailwind.css @theme, so the accent colour is
     defined in exactly one place. The literal is a fallback in case this file
     is ever loaded without the compiled stylesheet. */
  --accent: var(--color-brand-700, #17355f);
}

/* --------------------------------------------------------------------------
   Dark theme: the navy ramp

   Changed from the original green ramp to match the navy accent in
   assets/tailwind.css (itself regenerated from latex/user_guide/
   poraque_user_guide.tex's \definecolor block — see that file's comment).

   The templates say `dark:bg-slate-900`, `dark:border-slate-800`,
   `dark:text-slate-400` in a few hundred places, and Tailwind v4 compiles each
   of those to `var(--color-slate-N)`. Redefining those variables here — under
   `.dark` only, so light mode keeps the neutral slate — repaints every dark
   surface in one place instead of rewriting every template.

   The ramp holds the palette's hue throughout, desaturating as it lightens so
   the text steps stay readable rather than turning grey. 950 is the page
   background: #040d18, one step below the palette's own #0A1E3B (poraquecover,
   which stays in the scale as brand-950 — "cover ground only" in the LaTeX
   guide, and a page background is exactly that kind of ground).

   Contrast on that background: 400 (#91b2e2, poraquelime) is 9.0:1 — plenty
   for body text; 500 is 6.0:1 for the smaller muted notes. (Lower than the old
   green ramp's 12.9:1 / 7.9:1 on purpose, not an oversight: a saturated navy
   blue simply cannot reach the same relative luminance as a yellow-green at
   the same lightness — the WCAG formula weights green far more than blue.
   Both numbers still clear AA comfortably.) Every other step is a
   lime-to-near-black interpolation that keeps the same hue as brand-*, so a
   panel border or a hover state never reads as a different colour family from
   the accent it sits next to.

   Unlayered, so it beats Tailwind's `@layer theme` regardless of source order.
   -------------------------------------------------------------------------- */

.dark {
  --color-slate-50:  #f3f6f9;
  --color-slate-100: #d4dfee;
  --color-slate-200: #bccee8;
  --color-slate-300: #a5bfe4;
  --color-slate-400: #91b2e2;
  --color-slate-500: #6690cc;
  --color-slate-600: #3972c1;
  --color-slate-700: #275596;
  --color-slate-800: #163765;
  --color-slate-900: #0b1e38;
  --color-slate-950: #040d18;

  --surface: rgba(11, 30, 56, 0.5);   /* slate-900 / 50 */
  --surface-border: #163765;          /* slate-800 */
  --grid-line: rgba(145, 178, 226, 0.28);  /* bumped from 0.06, see :root */
  --accent: var(--color-brand-400, #91b2e2);
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

body {
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection {
  background-color: color-mix(in srgb, var(--accent) 22%, transparent);
}

/* A visible, consistent focus ring for keyboard users on every interactive
   element, without showing it on mouse clicks. */
:where(a, button, input, textarea, select, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 0.5rem;
}

/* --------------------------------------------------------------------------
   Card surface
   Used by .card throughout the templates so every panel shares one treatment.
   -------------------------------------------------------------------------- */

.card {
  background-color: var(--surface);
  border: 1px solid var(--surface-border);
  border-radius: 1rem;
  transition: border-color 200ms ease, box-shadow 200ms ease, transform 200ms ease;
}

.card:hover {
  border-color: color-mix(in srgb, var(--accent) 35%, var(--surface-border));
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 8px 24px -12px rgba(15, 23, 42, 0.18);
}

/* Only lift cards that are themselves links or contain a stretched link. */
a.card:hover,
.card:has(.link-cover):hover {
  transform: translateY(-2px);
}

.dark .card:hover {
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 8px 24px -12px rgba(0, 0, 0, 0.6);
}

/* Makes a single <a> cover its nearest positioned ancestor, so a whole card is
   clickable while the DOM keeps exactly one link (better for screen readers). */
.card:has(.link-cover) { position: relative; }

.link-cover::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

/* --------------------------------------------------------------------------
   Hero dot texture

   A dot lattice rather than a 1px line grid — one radial-gradient circle per
   tile, anchored `at 0 0` so the dot sits on each tile's own corner. Tiled
   edge-to-edge, that reconstitutes a full dot exactly on every grid
   intersection (four tiles each contribute a quarter-arc), so the lattice
   lands on the same 56px points a line grid would have crossed at.

   The mask lives on a pseudo-element, not on .bg-grid itself. A mask applies to
   an element AND everything inside it, so masking the section faded out the
   headline, the paragraph and the buttons along with the texture — the hero
   read as if it were behind fog. Only the texture should fade.

   `isolation: isolate` keeps the z-index: -1 layer inside the section, above
   the section's own background and below its content.
   -------------------------------------------------------------------------- */

.bg-grid {
  position: relative;
  isolation: isolate;
}

.bg-grid::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: radial-gradient(circle at 0 0, var(--grid-line) 2px, transparent 2px);
  background-size: 56px 56px;
  /* Fade the grid out towards the bottom so it never fights the content. */
  mask-image: radial-gradient(ellipse 90% 70% at 50% 0%, #000 25%, transparent 90%);
  -webkit-mask-image: radial-gradient(ellipse 90% 70% at 50% 0%, #000 25%, transparent 90%);
}

/* --------------------------------------------------------------------------
   Entrance animation
   Staggered via .reveal-1 … .reveal-5 on the hero elements.
   -------------------------------------------------------------------------- */

@keyframes reveal-up {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

.reveal {
  animation: reveal-up 620ms cubic-bezier(0.22, 1, 0.36, 1) backwards;
}

.reveal-1 { animation-delay: 70ms; }
.reveal-2 { animation-delay: 140ms; }
.reveal-3 { animation-delay: 210ms; }
.reveal-4 { animation-delay: 280ms; }
.reveal-5 { animation-delay: 350ms; }

/* --------------------------------------------------------------------------
   Scrollbar
   -------------------------------------------------------------------------- */

@media (min-width: 768px) {
  * {
    scrollbar-width: thin;
    scrollbar-color: #cbd5e1 transparent;
  }
  .dark * {
    scrollbar-color: #234331 transparent;
  }
}

/* ==========================================================================
   Poraquê-only, from here down
   ========================================================================== */

/* --------------------------------------------------------------------------
   Wordmark
   Two PNGs — dark artwork for light backgrounds, light for dark — swapped by
   the theme class rather than prefers-color-scheme, so the header toggle moves
   the logo too. The aspect ratio is fixed here so the header does not jump
   while the image loads.
   -------------------------------------------------------------------------- */

.wordmark {
  aspect-ratio: 4 / 1;
  width: auto;
  object-fit: contain;
}

/* --------------------------------------------------------------------------
   Caveat card (/foundation-models)
   A left rule in amber, matching the LaTeX user guide's own warning-box
   convention (\definecolor{warnamber}, framerule 2.4pt). A dedicated class
   rather than Tailwind's border-l-amber-500 utility: .card's own `border`
   shorthand below is unlayered CSS loaded after tailwind.css, so it always
   wins the cascade against a Tailwind utility regardless of source order —
   the shorthand would silently reset border-left-color right back to
   --surface-border. Declaring the override in the same unlayered stylesheet,
   after .card, is what actually wins.
   -------------------------------------------------------------------------- */

.card-warn {
  border-left-width: 4px;
  border-left-color: var(--color-amber-500, #b07d2a);
}

/* --------------------------------------------------------------------------
   Command blocks
   Install and training commands are long single lines. They must scroll
   inside their own box rather than widening the page on a phone.
   -------------------------------------------------------------------------- */

.code-block {
  overflow-x: auto;
  border-radius: 0.75rem;
  border: 1px solid var(--surface-border);
  background-color: #020a06;      /* deepest green — dark in both themes, like a
                                     terminal. Stays below the dark page background
                                     (#030f0a) so the block still reads as recessed
                                     rather than raised; in light mode this is a
                                     dark panel on near-white, where the colour
                                     does the work of separating it from the page. */
  color: #dcecdf;
  padding: 1rem 1.125rem;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.8125rem;
  line-height: 1.7;
  -webkit-overflow-scrolling: touch;
}

.dark .code-block {
  border-color: #234331;
}

/* Tighter variant for one-liners inside a card. A modifier class rather than
   Tailwind's important suffix, because .code-block lives in an unlayered
   stylesheet and would otherwise need `py-2.5!` to be overridden at all. */
.code-block-compact {
  padding: 0.625rem 0.875rem;
  font-size: 0.75rem;
}

.code-block code {
  display: block;
  white-space: pre;
}

/* Must come after `.code-block code` — same specificity, so source order is
   what decides. These are single commands inside a narrow card: wrapping reads
   better than a horizontal scrollbar the reader has to discover, and the
   hanging indent keeps the continuation clear of the prompt. */
.code-block-compact code {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  padding-left: 1.1em;
  text-indent: -1.1em;
}

/* Shell prompts and comments, marked up with <span> in the template.
   Matches --color-slate-400/500 (the poraquelime step and its dimmer
   neighbour) — hardcoded rather than var()'d because .code-block is dark
   in both themes, so it always wants the dark-mode ramp's values. */
.code-block .tok-prompt { color: #91b2e2; user-select: none; }
.code-block .tok-comment { color: #6690cc; }

/* --------------------------------------------------------------------------
   Accessibility: respect reduced-motion preferences
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .card:hover { transform: none; }
}
