@import "tailwindcss";

/* Self-hosted fonts — served via Propshaft (URLs rewritten to digested paths at compile time) */

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/jetbrains-mono-400-849c32ea.woff2") format("woff2");
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/jetbrains-mono-600-eee40bb0.woff2") format("woff2");
}

@font-face {
  font-family: "Saira Condensed";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/saira-condensed-400-ab14c79b.woff2") format("woff2");
}

@font-face {
  font-family: "Saira Condensed";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/assets/saira-condensed-500-ed17f249.woff2") format("woff2");
}

@font-face {
  font-family: "Saira Condensed";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/saira-condensed-600-5baaa405.woff2") format("woff2");
}

@font-face {
  font-family: "Saira Condensed";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/saira-condensed-700-11404b59.woff2") format("woff2");
}

@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("/assets/space-grotesk-300-2876ead4.woff2") format("woff2");
}

@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/space-grotesk-400-b217bce7.woff2") format("woff2");
}

@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/assets/space-grotesk-500-4b7aea1d.woff2") format("woff2");
}

@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/space-grotesk-600-ab3ffa9f.woff2") format("woff2");
}

@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/space-grotesk-700-36c6c9a5.woff2") format("woff2");
}

@theme {
  /* Background layers */
  --color-bg: #0A0C0F;
  --color-surface: #14181D;
  --color-surface-raised: #1C2128;
  --color-line: #262C34;

  /* Brand */
  --color-primary: #E2001A;

  /* Text */
  --color-text: #F2F4F7;
  --color-muted: #9AA4B2;

  /* Data-semantic accents */
  --color-accent-purple: #A855F7;
  --color-accent-green: #22C55E;
  --color-accent-amber: #F59E0B;
  --color-accent-blue: #2F8FFF;

  /* Diagnostic error colours — resolved by JS via getComputedStyle so canvas/WebGL
     can read the same tokens without hardcoding hex in JavaScript. */
  --color-error-collision: #ff3b30;
  /* Severity ladder: floating (amber) → off-platform (orange) → collision (red) */
  --color-warn-off-platform: #F97316;

  /* Track canvas */
  --color-asphalt: #141414;

  /* Typography */
  --font-display: "Saira Condensed", system-ui, sans-serif;
  --font-sans: "Space Grotesk", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;
}

/* Themed scrollbars — token-driven so they adapt automatically if light-mode tokens
   are ever introduced. Firefox uses scrollbar-width/color; WebKit uses the pseudo-
   element API. Goal: a thin, rounded, low-contrast thumb that recedes into dark
   surfaces but is still a visible affordance, brightening on hover. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--color-line) transparent;
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  background: var(--color-line);
  border-radius: 9999px;
  border: 2px solid transparent;
  background-clip: padding-box;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--color-muted);
  background-clip: padding-box;
}

/* Catalog thumbnail footprint classes — consumed by catalog_piece_controller.js.
   Using hand-written CSS so token-referenced fills compile regardless of whether
   the class names appear in scanned template files (Tailwind v4 JIT cannot see
   dynamically assigned class strings set from JavaScript). */
.footprint-fill {
  fill: var(--color-asphalt);
}

.footprint-slot {
  stroke: var(--color-line);
  stroke-width: 3;
}

.footprint-marking {
  stroke: var(--color-text);
  stroke-width: 1.5;
}

.footprint-marking--dashed {
  stroke-dasharray: 12 8;
}

.footprint-apron {
  fill: var(--color-muted);
}

/* .footprint-curb fill is set inline via url(#pattern-id) from the controller. */

/* Rail tab triggers — aria-selected drives the active underline so the
   controller only needs to set the attribute, not juggle classes. */
.tab-trigger {
  @apply border-b-2 border-transparent font-mono text-[10px] tracking-[0.2em] uppercase transition text-muted;
}
.tab-trigger:hover {
  @apply text-text;
}
.tab-trigger[aria-selected="true"] {
  @apply border-primary text-text;
}

/* Palette drag-to-snap affordances — .palette-dragging and .is-dragging are
   toggled dynamically by planner_controller.js's #setPaletteDragAffordance,
   so (like .footprint-fill above) they're hand-written here rather than as
   scanned Tailwind utility classes — the JIT never sees a class string that
   only ever appears in a classList.toggle() call. */

/* While a palette drag is in flight the pointer stays captured by the
   source button for the whole gesture, even though the operator is looking
   at the canvas — force the grabbing cursor everywhere under the planner
   root so the drag reads clearly regardless of what's actually under the
   (captured) pointer. */
.palette-dragging,
.palette-dragging * {
  cursor: grabbing !important;
}

/* The palette item currently being dragged — "you're carrying this piece". */
.is-dragging {
  @apply ring-2 ring-primary opacity-60;
}

/* Sinks a disabled assembly action item (hairpin, pit lane) to the bottom of
   the palette grid, so an ineligible multi-piece item never leads ahead of a
   placeable one — default grid items sit at order: 0. */
.palette-item-sunk {
  order: 1;
}

/* Lexxy editor — map to Telemetry Dark tokens.
   Dark is the default; no light-mode split needed for this app. */
lexxy-editor {
  --lexxy-color-canvas: var(--color-surface-raised);
  --lexxy-color-ink: var(--color-text);
  --lexxy-color-ink-medium: var(--color-muted);
  --lexxy-color-ink-light: var(--color-line);
  --lexxy-color-ink-lighter: var(--color-line);
  --lexxy-color-ink-lightest: var(--color-surface);
  --lexxy-color-ink-inverted: var(--color-surface);
  --lexxy-color-text: var(--color-text);
  --lexxy-color-text-subtle: var(--color-muted);
  --lexxy-font-base: var(--font-sans);

  border-color: var(--color-line);
  border-radius: 0.375rem;
}

/* Lexxy rendered content — wraps Action Text output via _content.html.erb */
.lexxy-content {
  color: var(--color-text);
  line-height: 1.625;
}

/* Blueprint grid — the planner canvas background.
   Faint 1px lines on a ~28px grid over the deep canvas surface.
   Hand-written so the class name is always present for the JIT scanner. */
.blueprint-grid {
  background-color: #0b0e12;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.045) 1px, transparent 1px);
  background-size: 28px 28px;
}
