/* ==========================================================================
   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 print rules for the CV.

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

: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, #2570eb);
}

.dark {
  --surface: rgba(15, 23, 42, 0.5);   /* slate-900 / 50 */
  --surface-border: #1e293b;          /* slate-800 */
  --grid-line: rgba(148, 163, 184, 0.07);
  --accent: var(--color-brand-400, #60aefa);
}

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

/* --------------------------------------------------------------------------
   Product logo tile
   The Poraquê and Calango marks are transparent PNGs drawn almost entirely in
   black, so they need a light plate underneath — in dark mode especially,
   where the page background would otherwise swallow them. Size and padding
   come from utility classes at the call site; only the plate lives here.
   -------------------------------------------------------------------------- */

.logo-tile {
  /* Flex, not grid: the two marks have different aspect ratios, and a flex
     container with a fixed height gives `max-height: 100%` below something
     definite to resolve against. In a grid the auto row would size itself to
     the image and the taller mark would spill out of the tile. */
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #ffffff;
  border: 1px solid var(--surface-border);
  border-radius: 1rem;
}

.dark .logo-tile {
  /* slate-200 rather than pure white: bright enough for black artwork,
     without punching a hole in the dark page. */
  background-color: #e2e8f0;
  border-color: #334155;
}

.logo-tile img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

/* --------------------------------------------------------------------------
   Hero grid texture
   -------------------------------------------------------------------------- */

.bg-grid {
  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 80% 60% at 50% 0%, #000 40%, transparent 100%);
  -webkit-mask-image: radial-gradient(ellipse 80% 60% at 50% 0%, #000 40%, transparent 100%);
}

/* --------------------------------------------------------------------------
   Collaboration graph
   vis-network draws to a <canvas> and ships its own tooltip element, so the
   only styling it can pick up from the site is what we override here. Node and
   edge colours live in static/js/network.js — canvas can't read CSS classes.
   -------------------------------------------------------------------------- */

/* The graph settles into a roughly circular shape, so on a wide container it is
   the height that limits how large fit() can draw it. Extra height buys back
   the label size that the wider spacing costs. */
#collab-graph {
  height: 28rem;
  border-radius: 1rem;
  background-color: var(--surface);
  border: 1px solid var(--surface-border);
  touch-action: pan-y;              /* keep vertical page scroll on phones */
}

@media (min-width: 640px) {
  #collab-graph { height: 36rem; }
}

#collab-graph:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* vis-network's default tooltip is a yellow sticky note. Restyle the container
   itself — not just our own markup inside it — so the plain-string tooltips on
   edges and cluster bubbles get the same treatment. */
.vis-tooltip {
  max-width: 17rem !important;
  padding: 0.625rem 0.75rem !important;
  border: 0 !important;
  border-radius: 0.625rem !important;
  background-color: #0f172a !important;   /* slate-900 */
  color: #f8fafc !important;
  font-family: inherit !important;
  font-size: 0.8125rem !important;
  line-height: 1.4 !important;
  white-space: normal !important;
  box-shadow: 0 10px 30px -12px rgba(15, 23, 42, 0.5) !important;
}

.dark .vis-tooltip {
  background-color: #e2e8f0 !important;
  color: #0f172a !important;
}

/* Node tooltips add structure on top of that card. */
.collab-tip {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}

.collab-tip strong { font-weight: 600; }

.collab-tip-meta {
  margin-top: 0.25rem;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.6875rem;
  opacity: 0.75;
}

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

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

/* --------------------------------------------------------------------------
   Print — mainly for the CV page
   -------------------------------------------------------------------------- */

@media print {
  header[class*="sticky"],
  footer,
  .print\:hidden {
    display: none !important;
  }

  body {
    background: #fff !important;
    color: #000 !important;
    font-size: 11pt;
  }

  .card {
    border: 1px solid #ddd !important;
    box-shadow: none !important;
    break-inside: avoid;
  }

  section, li, article {
    break-inside: avoid;
  }

  a {
    color: #000 !important;
    text-decoration: none !important;
  }

  /* .solid-panel marks a block that relies on a filled background for its white
     text — the availability banner. Browsers drop backgrounds when printing,
     which would leave it white on white, so restate it as bordered black text. */
  .solid-panel {
    background: #fff !important;
    border: 1px solid #999 !important;
  }

  .solid-panel * {
    color: #000 !important;
    border-color: #999 !important;
  }
}
