/* ==========================================================================
   mandacaru.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 grid 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 poraque.seixas.dev/static/css/style.css and
   calango-studio.seixas.dev/static/css/style.css. Everything through the scrollbar
   section is byte-identical on purpose, so the four sites keep looking like
   one family; the parts unique to this product (.code-block, .card-warn,
   .wordmark) are added at the end.
   ========================================================================== */

:root {
  --surface: #ffffff;
  --surface-border: #e2e8f0;      /* slate-200 */
  --grid-line: rgba(15, 23, 42, 0.055);
  /* 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, #0f3d2e);
}

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

   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, #030f0a — one step below the palette's own #06231b, which stays
   in the scale as brand-950. Contrast on that background: 400 (#a3c64b) is
   12.9:1, plenty for body text, and 500 is 7.9:1 for the smaller muted notes.
   Every other step keeps the same hue as brand-*, so a panel border or a hover
   state never reads as a different colour family from the accent beside it.

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

.dark {
  --color-slate-50:  #eef7f1;
  --color-slate-100: #dcecdf;
  --color-slate-200: #c3ddc7;
  --color-slate-300: #a3c9a8;
  --color-slate-400: #a3c64b;
  --color-slate-500: #7a9d5f;
  --color-slate-600: #5c7d52;
  --color-slate-700: #3f5f42;
  --color-slate-800: #234331;
  --color-slate-900: #142d20;
  --color-slate-950: #030f0a;

  --surface: rgba(20, 45, 32, 0.5);   /* slate-900 / 50 */
  --surface-border: #234331;          /* slate-800 */
  --grid-line: rgba(163, 198, 75, 0.06);
  --accent: var(--color-brand-400, #a3c64b);
}

/* --------------------------------------------------------------------------
   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 grid texture

   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:
    linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
  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;
  }
}

/* ==========================================================================
   Mandacaru-only, from here down
   ========================================================================== */

/* --------------------------------------------------------------------------
   Wordmark
   Two PNGs — the shipped logo/logo_light.png and logo/logo_dark.png, trimmed
   to their own ink — 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.2 / 1;
  width: auto;
  object-fit: contain;
}

/* --------------------------------------------------------------------------
   Warning cards
   Used on /hardware for the honestly-labelled gaps (error mitigation is not
   written, the grid's egg-box, relaxation on a surface with no minimum) — a
   left rule in the ember accent rather than the green brand, so a caveat
   never reads as more brand chrome.
   -------------------------------------------------------------------------- */

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

/* --------------------------------------------------------------------------
   Command blocks
   Install instructions 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. */
  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. */
.code-block .tok-prompt { color: #a3c64b; user-select: none; }
.code-block .tok-comment { color: #7a9d5f; }

/* --------------------------------------------------------------------------
   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; }
}
