/* ==========================================================================
   calango-studio.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 /download.

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

   Deliberately a near-copy of seixas.dev/static/css/style.css. The parts that
   site needs and this one does not (collaboration graph, CV print rules) are
   gone; the parts unique to a product page (.code-block, .wordmark) are added
   at the end. Everything in between is byte-identical on purpose, so the two
   sites keep looking like one family.
   ========================================================================== */

: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-600, #d51c39);
}

/* --------------------------------------------------------------------------
   Dark theme: the wine 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 pink. 950 is the page
   background: #100005, two shades below the palette's #4F0020, which stays in
   the scale as brand-950. Contrast on that background: 400 is 10.4:1 (body
   text), 500 is 6.6:1 (the small muted notes).

   Every other step is unchanged from the #280010 this replaced. Darkening only
   950 lifts every contrast ratio on the page — nothing needed compensating.

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

.dark {
  --color-slate-50:  #fdf4f8;
  --color-slate-100: #faebf1;
  --color-slate-200: #f4dde6;
  --color-slate-300: #e8c9d6;
  --color-slate-400: #d5aebe;
  --color-slate-500: #b98399;
  --color-slate-600: #9f5673;
  --color-slate-700: #863c5a;
  --color-slate-800: #6f2543;
  --color-slate-900: #5f1130;
  --color-slate-950: #100005;

  --surface: rgba(95, 17, 48, 0.5);   /* slate-900 / 50 */
  --surface-border: #6f2543;          /* slate-800 */
  --grid-line: rgba(255, 150, 180, 0.05);
  --accent: var(--color-brand-400, #ff6060);
}

/* --------------------------------------------------------------------------
   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: #863c5a transparent;
  }
}

/* ==========================================================================
   Calango Studio-only, from here down
   ========================================================================== */

/* --------------------------------------------------------------------------
   Wordmark
   Two PNGs — black artwork for light backgrounds, white 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;
}

/* --------------------------------------------------------------------------
   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: #050002;      /* deepest wine — dark in both themes, like a terminal.
                                     Stays below the dark page background (#100005) so the
                                     block still reads as recessed rather than raised. At a
                                     page this close to black the luminance step is only
                                     1.02:1, so in dark mode it is really the wine border
                                     below that draws the boundary; the colour still matters
                                     in light mode, where this is a dark panel on near-white. */
  color: #f4dde6;
  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: #6f2543;
}

/* 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: #ff6060; user-select: none; }
.code-block .tok-comment { color: #b98399; }

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