/*
 * Ring Zero Design — theme overrides on top of Bulma 1.x.
 *
 * Bulma 1.x derives its entire palette from CSS variables, so the
 * blue/gray/black look is achieved by overriding a handful of them here.
 * Every page sets <html data-theme="dark"> to force Bulma's dark scheme
 * regardless of the visitor's OS preference; these overrides then shift
 * the neutral grays toward blue and pick a steel-blue accent.
 */

/* --- Self-hosted webfonts (fonts/, no CDN at runtime) ------------------
 * Chakra Petch: display face for headlines, nav, buttons.
 * Inter: variable font (one file covers all weights) for body text.
 */
@font-face {
  font-family: "Chakra Petch";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/chakra-petch-500.woff2") format("woff2");
}
@font-face {
  font-family: "Chakra Petch";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/chakra-petch-700.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900; /* variable font: single file, full weight range */
  font-display: swap;
  src: url("../fonts/inter-var.woff2") format("woff2");
}

:root,
[data-theme="dark"] {
  /* Hue/saturation used by ALL of Bulma's grays — pushes them blue. */
  --bulma-scheme-h: 215;
  --bulma-scheme-s: 28%;

  /* Steel-blue links / accents (Bulma builds link colors from these). */
  --bulma-link-h: 210;
  --bulma-link-s: 58%;
  --bulma-link-l: 60%;

  /* Primary follows the same accent so buttons/tags match. */
  --bulma-primary-h: 210;
  --bulma-primary-s: 58%;
  --bulma-primary-l: 60%;

  /* Page background: near-black blue. */
  --bulma-body-background-color: #0a0e14;

  /* Named colors used directly below (kept as plain variables so the
     palette lives in one place). */
  --ef-panel: #141b26;
  --ef-border: #2a3648;
  --ef-text: #c3cede;
  --ef-heading: #eef2f8;
  --ef-accent: #5b9dd9;
}

body {
  color: var(--ef-text);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 1.0625rem; /* Inter reads small at 1rem */
}

/* --- Sci-fi headline treatment (matches the EVE Frontier reference) --- */

.title,
.navbar-item,
.button {
  font-family: "Chakra Petch", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

.title,
.navbar-item[data-scramble],
.button {
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.title {
  color: var(--ef-heading);
}

/* Fluid type scale: huge on desktop, sane on phones. Tighter tracking than
   the shared .title 0.08em — at this size "Ring Zero Design" needs the room
   to stay on one line in the widened .hero-copy column below. */
.hero .title.is-1 {
  font-size: clamp(2.2rem, 6vw, 4rem);
  letter-spacing: 0.03em;
}

.title.is-2 {
  font-size: clamp(2rem, 4vw, 3rem);
}

.title.is-3 {
  font-size: clamp(1.6rem, 3vw, 2.4rem);
}

/* Roomier vertical rhythm between sections. */
.section {
  padding: 4.5rem 1.5rem;
}

/* Comfortable reading measure for prose blocks. The .container.prose
   variant matches the specificity of Bulma's `.container:not(...)`
   breakpoint rules, which would otherwise win and stretch the page. */
.prose,
.container.prose {
  max-width: 42rem;
}

/* Thin accent rule under section titles, like the reference site. */
.section .title::after {
  content: "";
  display: block;
  width: 3rem;
  height: 2px;
  margin-top: 0.5rem;
  background: var(--ef-accent);
}

/* Page titles (is-2) get a full-width grid line fading out to the right —
   a faint echo of the hero constellation on inner pages. */
.section .title.is-2::after {
  width: 100%;
  background: linear-gradient(90deg,
    var(--ef-accent) 0, var(--ef-accent) 3rem,
    var(--ef-border) 3rem, transparent 100%);
}

/* --- HUD data labels ---
 * Tiny monospace all-caps tags used everywhere the theme needs a telemetry
 * voice: section kickers ("01 / SERVICES"), hero telemetry, card indices,
 * OUTPUT lines, footer status, contact channel rows. Dim variants use
 * Bulma's has-text-grey helper.
 */
.data-label {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ef-accent);
}

/* --- Panels / cards --- */

/* HUD corner brackets instead of a full border: eight thin gradient strips
   (a horizontal + vertical pair per corner) drawn as background images.
   --hud sets their color; hover swaps it to the accent. */
.card,
.box {
  --hud: var(--ef-border);
  background-color: var(--ef-panel);
  background-image:
    linear-gradient(var(--hud), var(--hud)), linear-gradient(var(--hud), var(--hud)),
    linear-gradient(var(--hud), var(--hud)), linear-gradient(var(--hud), var(--hud)),
    linear-gradient(var(--hud), var(--hud)), linear-gradient(var(--hud), var(--hud)),
    linear-gradient(var(--hud), var(--hud)), linear-gradient(var(--hud), var(--hud));
  background-repeat: no-repeat;
  background-size:
    14px 1px, 1px 14px,   /* top-left */
    14px 1px, 1px 14px,   /* top-right */
    14px 1px, 1px 14px,   /* bottom-left */
    14px 1px, 1px 14px;   /* bottom-right */
  background-position:
    top left, top left,
    top right, top right,
    bottom left, bottom left,
    bottom right, bottom right;
  border: none;
  border-radius: 0; /* squarer, more "console" than Bulma's default */
  transition: transform 150ms ease, box-shadow 150ms ease;
}

.card:hover,
.box:hover {
  --hud: var(--ef-accent);
  transform: translateY(-3px);
  box-shadow: 0 6px 18px rgba(91, 157, 217, 0.15);
}

/* Contact page: label/value rows inside the channel panel. */
.channel-row {
  display: flex;
  align-items: baseline;
  gap: 1.5rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--ef-border);
}

.channel-row:last-child {
  border-bottom: none;
}

.channel-row .data-label {
  min-width: 6.5rem;
}

.navbar {
  display: flex; /* nav has no .container wrapper, so Bulma's usual .navbar>.container flex never applies */
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 30;
  background: rgba(10, 14, 20, 0.25);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--ef-border);
}

/* Nav floats over content now, so the page underneath must compensate:
   the hero (index.html only) grows to true full-viewport height, and the
   plain .section pages (which have no hero) get the navbar height added
   back into their top padding so content doesn't start under the bar. */
.navbar + .hero {
  min-height: 100vh;
}

.navbar + .section {
  padding-top: calc(4.5rem + var(--bulma-navbar-height));
}

.navbar-brand .navbar-item {
  min-width: 170px; /* flex-basis:auto under-measures the nested flex+inline-block wordmark (a Chromium intrinsic-sizing quirk), clipping it under the burger; a concrete floor sidesteps the bad measurement */
}

.footer {
  background: var(--ef-panel);
  border-top: 1px solid var(--ef-border);
  padding: 1.75rem 1.5rem;
}

/* --- Hero --- */

.hero.is-fullheight-with-navbar,
.hero,
.page-hero {
  background:
    radial-gradient(ellipse at 70% 20%, rgba(91, 157, 217, 0.12), transparent 60%),
    var(--bulma-body-background-color);
}

.hero .subtitle {
  color: var(--ef-text);
}

/* three.js "neural constellation" canvas. Fills the hero (index.html) or the
   compact page-hero band (every other page's header) behind the text;
   pointer-events off so links/buttons stay clickable. */
.hero,
.page-hero {
  position: relative;
  overflow: hidden;
}

#hero-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0.48; /* keep headline contrast (0.8 × 0.6 — dimmed 40% by request) */
}

.hero .hero-body,
.page-hero > .container {
  position: relative; /* stack above the canvas */
  z-index: 1;
}

/* page-hero is just a title band, not a full section — trim the bottom
   padding so it doesn't duplicate the section below it's own top padding. */
.page-hero {
  padding-bottom: 2rem;
}

/* Asymmetric hero: copy block capped left, telemetry rail on the right
   (desktop only — the rail carries is-hidden-mobile in the markup). Widened
   from 34rem so the title (below) has room to sit on one line. */
.hero-copy {
  max-width: 48rem;
}

/* Let the telemetry rail drop below the copy instead of squeezing it at
   mid desktop widths, now that the copy column is wider. */
.hero-body > .container {
  flex-wrap: wrap;
  row-gap: 2rem;
}

.hero-telemetry {
  border-left: 1px solid var(--ef-border);
  padding-left: 1.25rem;
}

.hero-telemetry .data-label {
  display: block;
}

.hero-telemetry .data-label + .data-label {
  margin-top: 0.6rem;
}

/* Bobbing chevron at the bottom of the full-height hero: a rotated square
   with two visible edges. `translate` animates separately from the
   rotate/center transform, so the two don't fight. */
.scroll-cue {
  position: absolute;
  bottom: 2rem;
  left: 50%;
  z-index: 1;
  width: 1.25rem;
  height: 1.25rem;
  border-right: 2px solid var(--ef-accent);
  border-bottom: 2px solid var(--ef-accent);
  transform: translateX(-50%) rotate(45deg);
  animation: cue-bob 2s ease-in-out infinite;
}

@keyframes cue-bob {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 8px; }
}

/* --- Buttons: HUD console style with a dissolving corner ---
 * One corner of each button "dissolves" into checkerboard pixels; the
 * .dissolve-tl/-tr/-bl/-br class on the button picks which (hand-assigned,
 * varied across the site). The border is drawn as background gradients so
 * the dissolve corner can trade its solid lines for pixel dust — a real
 * border can't be partially erased, and a CSS mask would clip the hover
 * glow (and must work over the hero canvas).
 * --dis is the size of the dissolved region: partial at rest, and hover
 * pushes the decay deeper in discrete steps(3) jumps to match the scramble
 * effect's digital feel, reversing on mouse-out.
 */
@property --dis {
  syntax: "<length>";
  inherits: false;
  initial-value: 18px;
}

.button {
  --hud: var(--ef-border);
  --hud2: var(--ef-heading); /* second checker color — alternates with --hud in the scatter */
  --dis: 18px; /* also the fallback where @property is unsupported */
  background-color: transparent;
  border: 1px solid var(--ef-border);
  border-radius: 0;
  color: var(--ef-heading);
  transition: --dis 200ms steps(3), box-shadow 150ms ease;
}

.button:hover {
  --hud: var(--ef-accent);
  --dis: 30px;
  border-color: var(--ef-accent);
  color: var(--ef-accent);
  box-shadow: 0 0 12px rgba(91, 157, 217, 0.35);
}

.button:focus-visible {
  outline: 2px solid var(--ef-accent);
  outline-offset: 3px;
}

/* Gradient-drawn border for the dissolve variants: two full edges, two
   edges shortened by --dis at the dissolve corner, dashed "pixel" tails
   finishing those edges, and one offset scatter strip per axis for the
   2D checkerboard decay. Layer order (and sizes) are identical for all
   four variants — only background-position differs per corner. Each
   scatter cell cycles --hud, then --hud2, then a gap — a real two-color
   checker instead of a single color dashed against transparent. */
.button[class*="dissolve-"] {
  border: none;
  background-repeat: no-repeat;
  background-image:
    linear-gradient(var(--hud), var(--hud)),
    linear-gradient(var(--hud), var(--hud)),
    linear-gradient(var(--hud), var(--hud)),
    linear-gradient(var(--hud), var(--hud)),
    repeating-linear-gradient(90deg, var(--hud) 0 3px, var(--hud2) 3px 6px, transparent 6px 10px),
    repeating-linear-gradient(180deg, var(--hud) 0 3px, var(--hud2) 3px 6px, transparent 6px 10px),
    repeating-linear-gradient(90deg, var(--hud) 0 3px, var(--hud2) 3px 6px, transparent 6px 10px),
    repeating-linear-gradient(180deg, var(--hud) 0 3px, var(--hud2) 3px 6px, transparent 6px 10px);
  background-size:
    100% 1px,                      /* full edge, horizontal */
    1px 100%,                      /* full edge, vertical */
    calc(100% - var(--dis)) 1px,   /* shortened edge, horizontal */
    1px calc(100% - var(--dis)),   /* shortened edge, vertical */
    var(--dis) 1px,                /* pixel tail, horizontal */
    1px var(--dis),                /* pixel tail, vertical */
    calc(var(--dis) - 4px) 3px,    /* scatter strip, horizontal */
    3px calc(var(--dis) - 4px);    /* scatter strip, vertical */
}

.button.dissolve-br {
  background-position:
    top left, top left,
    bottom left, top right,
    bottom right, bottom right,
    right 0 bottom 3px, right 3px bottom 0;
}

.button.dissolve-bl {
  background-position:
    top left, top right,
    bottom right, top left,
    bottom left, bottom left,
    left 0 bottom 3px, left 3px bottom 0;
}

.button.dissolve-tr {
  background-position:
    bottom left, top left,
    top left, bottom right,
    top right, top right,
    right 0 top 3px, right 3px top 0;
}

.button.dissolve-tl {
  background-position:
    bottom left, top right,
    top right, bottom left,
    top left, top left,
    left 0 top 3px, left 3px top 0;
}

/* Motion-sensitive users: no lifts, no bobbing. (scramble.js and
   hero-bg.js check this in JS and never start.) */
@media (prefers-reduced-motion: reduce) {
  .card, .box {
    transition: none;
  }
  .card:hover, .box:hover {
    transform: none;
  }
  .scroll-cue {
    animation: none;
  }
  .button {
    transition: none;
  }
  .button:hover {
    --dis: 18px; /* keep the static rest-state dissolve; no decay animation */
  }
}

/* --- Scramble effect support ---
 * Scrambled glyphs vary in width in proportional fonts; scramble.js sets an
 * inline min-width from the element's measured width, and this keeps the
 * text from wrapping or jittering while letters are cycling.
 */
[data-scramble] {
  display: inline-block;
}

/* Nav chrome must stay one line; headings are free to wrap on narrow screens. */
.navbar-item[data-scramble],
.navbar-brand [data-scramble] {
  white-space: nowrap;
}

/* [data-scramble]'s display:inline-block above wins over .navbar-item's
   display:flex (equal specificity, later in source), which drops the
   vertical centering that keeps nav links from top-aligning in the bar. */
.navbar-item[data-scramble] {
  display: flex;
}
