/* Leaflet map CSS (vendored) */ @import "../vendor/leaflet/leaflet.css"; /* Cascadia Code as the single project font. Google Fonts doesn't ship it — fonts.cdnfonts.com mirrors Microsoft's release. */ @import url('https://fonts.cdnfonts.com/css/cascadia-code'); /* See the Tailwind configuration guide for advanced usage https://tailwindcss.com/docs/configuration */ @import "tailwindcss" source(none); @source "../css"; @source "../js"; @source "../../lib/microwaveprop_web"; @source "../../deps/live_table/lib"; @source "../../deps/sutra_ui/lib"; /* Map both Tailwind font families onto Cascadia Code so any element hard-coded to font-sans or font-mono picks up the project font. Keep the system fallbacks so the page is still readable while the webfont network request is in flight. */ @theme { --font-sans: "Cascadia Code", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; --font-mono: "Cascadia Code", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; } /* live_table / sutra_ui compat: maps shadcn tokens live_table uses to daisyUI base colors and provides component CSS for the SutraUI primitives wrapped by live_table (select, input-group, dropdown, empty state). Must come before the daisyUI plugins so daisyUI's primary/accent/error tokens still win in @theme resolution. */ @import "./live_table_compat.css"; /* A Tailwind plugin that makes "hero-#{ICON}" classes available. The heroicons installation itself is managed by your mix.exs */ @plugin "../vendor/heroicons"; /* daisyUI Tailwind Plugin. You can update this file by fetching the latest version with: curl -sLO https://github.com/saadeghi/daisyui/releases/latest/download/daisyui.js Make sure to look at the daisyUI changelog: https://daisyui.com/docs/changelog/ */ @plugin "../vendor/daisyui" { themes: false; } /* daisyUI theme plugin. You can update this file by fetching the latest version with: curl -sLO https://github.com/saadeghi/daisyui/releases/latest/download/daisyui-theme.js We ship with two themes, a light one inspired on Phoenix colors and a dark one inspired on Elixir colors. Build your own at: https://daisyui.com/theme-generator/ */ /* NTMS Propagation Prediction — dark theme (primary). Navy-slate surfaces, indigo-violet accent. Values derived from the design-system handoff: bg-2 (#1E2230) is the elevated surface class (cards, nav), bg-1 (#161922) is the app body, bg-0 (#0F1218) is the deepest page fill. Kept in this codebase's base-100/200/300 convention where base-100 is the *lightest* dark surface (elevated). */ @plugin "../vendor/daisyui-theme" { name: "dark"; default: false; prefersdark: true; color-scheme: "dark"; --color-base-100: #1E2230; --color-base-200: #161922; --color-base-300: #0F1218; --color-base-content: #F5F6FA; --color-primary: #6366F1; --color-primary-content: #FFFFFF; --color-secondary: #7376F4; --color-secondary-content: #FFFFFF; --color-accent: #6366F1; --color-accent-content: #FFFFFF; --color-neutral: #262B3B; --color-neutral-content: #F5F6FA; --color-info: #60A5FA; --color-info-content: #0A1A2B; --color-success: #2BD4A4; --color-success-content: #052A1E; --color-warning: #F5A524; --color-warning-content: #2A1A00; --color-error: #F05674; --color-error-content: #FFFFFF; --radius-selector: 0.375rem; --radius-field: 0.375rem; --radius-box: 0.75rem; --size-selector: 0.21875rem; --size-field: 0.21875rem; --border: 1px; --depth: 0; --noise: 0; } @plugin "../vendor/daisyui-theme" { name: "light"; default: true; prefersdark: false; color-scheme: "light"; --color-base-100: #FFFFFF; --color-base-200: #F7F8FB; --color-base-300: #F1F3F8; --color-base-content: #10131C; --color-primary: #5458E3; --color-primary-content: #FFFFFF; --color-secondary: #4A4ED1; --color-secondary-content: #FFFFFF; --color-accent: #5458E3; --color-accent-content: #FFFFFF; --color-neutral: #323849; --color-neutral-content: #FFFFFF; --color-info: #2563EB; --color-info-content: #FFFFFF; --color-success: #149E74; --color-success-content: #FFFFFF; --color-warning: #C77700; --color-warning-content: #FFFFFF; --color-error: #D0324D; --color-error-content: #FFFFFF; --radius-selector: 0.375rem; --radius-field: 0.375rem; --radius-box: 0.75rem; --size-selector: 0.21875rem; --size-field: 0.21875rem; --border: 1px; --depth: 0; --noise: 0; } /* Add variants based on LiveView classes */ @custom-variant phx-click-loading (.phx-click-loading&, .phx-click-loading &); @custom-variant phx-submit-loading (.phx-submit-loading&, .phx-submit-loading &); @custom-variant phx-change-loading (.phx-change-loading&, .phx-change-loading &); /* Use the data attribute for dark mode */ @custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *)); /* Make LiveView wrapper divs transparent for layout */ [data-phx-session], [data-phx-teleported-src] { display: contents } /* ========================================================================== NTMS design tokens — propagation quality + band palette. Held outside daisyUI's theme plugin so they can be referenced directly from HEEx templates and JS hooks (e.g. the heatmap canvas). ========================================================================== */ :root, :root[data-theme="dark"] { --prop-excellent: #2BD4A4; --prop-good: #9FE6C8; --prop-marginal: #F5D968; --prop-poor: #F59E4B; --prop-negligible: #EF6B6B; --band-2m: #60A5FA; --band-70cm: #A78BFA; --band-23cm: #F472B6; --band-13cm: #FB7185; --band-9cm: #FB923C; --band-6cm: #FBBF24; --band-3cm: #A3E635; --band-1-25cm: #34D399; --band-6mm: #22D3EE; } :root[data-theme="light"] { --prop-excellent: #149E74; --prop-good: #5FC79D; --prop-marginal: #E5B83B; --prop-poor: #E58A3B; --prop-negligible: #D45757; --band-2m: #2563EB; --band-70cm: #7C3AED; --band-23cm: #DB2777; --band-13cm: #E11D48; --band-9cm: #EA580C; --band-6cm: #B45309; --band-3cm: #65A30D; --band-1-25cm: #059669; --band-6mm: #0891B2; } /* Cascadia Code everywhere — UI, body copy, and code. The font is monospace by design; we tighten letter-spacing slightly so prose blocks don't read excessively wide. */ html, body { font-family: "Cascadia Code", ui-monospace, SFMono-Regular, "Menlo", "Consolas", monospace; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; font-variant-numeric: tabular-nums; } /* Callsign / grid styling helpers. Sans with tight tracking in upper case; tabular digits so columns align. */ .callsign { font-weight: 600; letter-spacing: 0.02em; text-transform: uppercase; } .grid-square { font-weight: 500; color: var(--color-base-content); opacity: 0.85; } /* Fix daisyUI select text alignment — when select class is on the . */ select.select { margin: 0; display: flex; align-items: center; } /* Markdown rendered content — uses daisyUI theme variables for auto dark/light */ .markdown-content { max-width: 88rem; margin: 2rem auto; padding: 0 1rem; line-height: 1.75; color: var(--color-base-content); } .markdown-content h1 { font-size: 2rem; font-weight: 700; margin: 2rem 0 1rem; border-bottom: 1px solid var(--color-base-300); padding-bottom: 0.5rem; } .markdown-content h2 { font-size: 1.5rem; font-weight: 700; margin: 1.75rem 0 0.75rem; border-bottom: 1px solid var(--color-base-300); padding-bottom: 0.25rem; } .markdown-content h3 { font-size: 1.25rem; font-weight: 600; margin: 1.5rem 0 0.5rem; } .markdown-content h4 { font-size: 1.1rem; font-weight: 600; margin: 1.25rem 0 0.5rem; } .markdown-content p { margin: 0.75rem 0; } .markdown-content ul, .markdown-content ol { margin: 0.75rem 0; padding-left: 2rem; } .markdown-content ul { list-style-type: disc; } .markdown-content ol { list-style-type: decimal; } .markdown-content li { margin: 0.25rem 0; } .markdown-content code { font-family: "Cascadia Code", ui-monospace, monospace; font-size: 0.875em; background: var(--color-base-300); padding: 0.15em 0.35em; border-radius: 0.25rem; } .markdown-content pre { margin: 1rem 0; padding: 1rem; background: var(--color-neutral); color: var(--color-neutral-content); border-radius: 0.5rem; overflow-x: auto; } .markdown-content pre code { background: none; padding: 0; font-size: 0.85em; color: inherit; } .markdown-content table { display: block; overflow-x: auto; width: auto; max-width: 100%; border-collapse: collapse; margin: 1rem 0; font-size: 0.9em; } .markdown-content th, .markdown-content td { border: 1px solid var(--color-base-300); padding: 0.5rem 0.75rem; text-align: left; white-space: nowrap; } .markdown-content th { background: var(--color-base-300); font-weight: 600; } .markdown-content tbody tr:nth-child(even) { background: var(--color-base-200); } .markdown-content hr { border: none; border-top: 2px solid var(--color-base-300); margin: 2rem 0; } .markdown-content strong { font-weight: 700; } .markdown-content blockquote { border-left: 4px solid var(--color-primary); margin: 1rem 0; padding: 0.5rem 1rem; background: var(--color-base-200); } .markdown-content a { color: var(--color-primary); text-decoration: underline; } /* ───────────────────────────────────────────────────────────────────────── /docs/api — Tailwind UI "Protocol"-style API reference layout. Sidebar on the left, two-column body where prose sits next to a sticky code sample. Themed via daisyUI base-* tokens for auto light/dark. ───────────────────────────────────────────────────────────────────────── */ .api-docs-shell { --api-prose-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; --api-mono-font: "Cascadia Code", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; display: grid; grid-template-columns: 1fr; gap: 0; min-height: calc(100vh - 4rem); margin: -3rem -1rem 0; font-family: var(--api-prose-font); color: var(--color-base-content); } @media (min-width: 1024px) { .api-docs-shell { grid-template-columns: 17rem minmax(0, 1fr); margin: -3rem 0 0; } } .api-docs-sidebar { display: none; border-right: 1px solid var(--color-base-200); padding: 1.5rem 1.25rem 2rem 1.5rem; background: color-mix(in oklab, var(--color-base-100) 65%, transparent); } @media (min-width: 1024px) { .api-docs-sidebar { display: block; position: sticky; top: 4rem; height: calc(100vh - 4rem); overflow-y: auto; } } .api-docs-nav-group { margin-top: 1.5rem; } .api-docs-nav-group:first-child { margin-top: 0; } .api-docs-nav-group h3 { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-base-content); opacity: 0.7; margin: 0 0 0.5rem; } .api-docs-nav-group ul { display: flex; flex-direction: column; border-left: 1px solid var(--color-base-200); padding-left: 0; margin: 0; list-style: none; } .api-docs-nav-group li { margin: 0; } .api-docs-nav-group a { display: block; padding: 0.3rem 0 0.3rem 0.875rem; margin-left: -1px; font-size: 0.85rem; border-left: 1px solid transparent; color: var(--color-base-content); opacity: 0.7; text-decoration: none; transition: color 120ms, border-color 120ms, opacity 120ms; } .api-docs-nav-group a:hover { opacity: 1; color: var(--color-primary); } .api-docs-nav-group a:target, .api-docs-nav-group a:focus-visible { outline: none; opacity: 1; border-left-color: var(--color-primary); color: var(--color-primary); } .api-docs-main { min-width: 0; padding: 2rem 1rem 4rem; } @media (min-width: 768px) { .api-docs-main { padding: 2.5rem 2rem 5rem; } } .api-docs-prose { max-width: 76rem; margin: 0 auto; line-height: 1.7; } .api-docs-prose h1 { font-size: 2.25rem; font-weight: 700; letter-spacing: -0.02em; margin: 0 0 0.75rem; scroll-margin-top: 6rem; } .api-docs-prose h2 { font-size: 1.5rem; font-weight: 700; letter-spacing: -0.01em; margin: 0 0 0.75rem; scroll-margin-top: 6rem; } .api-docs-prose h3 { font-size: 1.125rem; font-weight: 600; margin: 1.5rem 0 0.5rem; } .api-docs-prose h4 { font-size: 0.95rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-base-content); opacity: 0.75; margin: 1.25rem 0 0.5rem; } .api-docs-prose p { margin: 0.75rem 0; } .api-docs-prose ul { list-style: disc; padding-left: 1.25rem; margin: 0.75rem 0; } .api-docs-prose ul li { margin: 0.35rem 0; } .api-docs-prose code { font-family: var(--api-mono-font); font-size: 0.85em; padding: 0.1em 0.35em; border-radius: 0.3rem; background: var(--color-base-200); color: var(--color-base-content); word-break: break-word; } .api-docs-prose table { width: 100%; border-collapse: collapse; margin: 0.75rem 0 1.25rem; font-size: 0.9rem; border: 1px solid var(--color-base-200); border-radius: 0.5rem; overflow: hidden; } .api-docs-prose th, .api-docs-prose td { text-align: left; padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--color-base-200); } .api-docs-prose th { background: var(--color-base-200); font-weight: 600; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.04em; } .api-docs-prose tbody tr:last-child td { border-bottom: 0; } .api-docs-link { color: var(--color-primary); text-decoration: underline; text-underline-offset: 2px; } .api-docs-link:hover { text-decoration-thickness: 2px; } /* ── Hero ─────────────────────────────────────────────────────────── */ .api-docs-hero { border-bottom: 1px solid var(--color-base-200); padding-bottom: 2rem; margin-bottom: 2.5rem; } .api-docs-eyebrow { font-family: var(--api-mono-font); font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.1em; color: var(--color-primary); margin: 0 0 0.5rem; } .api-docs-lead { font-size: 1.1rem; line-height: 1.6; opacity: 0.85; max-width: 52rem; } .api-docs-meta { display: grid; grid-template-columns: 1fr; gap: 0.75rem 2rem; margin: 1.5rem 0 0; padding: 1rem 1.25rem; border: 1px solid var(--color-base-200); border-radius: 0.75rem; background: color-mix(in oklab, var(--color-base-100) 60%, transparent); } @media (min-width: 768px) { .api-docs-meta { grid-template-columns: max-content 1fr; column-gap: 1.5rem; } .api-docs-meta > div { display: contents; } } .api-docs-meta dt { font-weight: 600; font-size: 0.85rem; opacity: 0.75; } .api-docs-meta dd { margin: 0; font-size: 0.9rem; } /* ── Two-column row (guide sections) + endpoint blocks ────────────── */ .api-docs-row, .api-docs-endpoint { display: grid; grid-template-columns: 1fr; gap: 1.25rem; scroll-margin-top: 6rem; padding-block: 2rem; border-top: 1px solid var(--color-base-200); } .api-docs-row:first-of-type, .api-docs-endpoint:first-of-type { border-top: 0; padding-top: 1rem; } @media (min-width: 1100px) { .api-docs-row, .api-docs-endpoint { grid-template-columns: minmax(0, 1fr) minmax(0, 28rem); gap: 2.5rem; } .api-docs-row-code, .api-docs-endpoint-code { position: sticky; top: 5rem; align-self: start; } } .api-docs-row-prose, .api-docs-endpoint-prose { min-width: 0; } .api-docs-row-code, .api-docs-endpoint-code { display: flex; flex-direction: column; gap: 1rem; min-width: 0; } .api-docs-section-heading { font-size: 1.75rem; font-weight: 700; letter-spacing: -0.01em; margin: 1.5rem 0 0.5rem; } .api-docs-divider { border: 0; height: 1px; background: var(--color-base-200); margin: 2.5rem 0 1rem; } .api-docs-callout { border-left: 3px solid var(--color-primary); background: color-mix(in oklab, var(--color-primary) 7%, transparent); padding: 0.6rem 0.9rem; border-radius: 0 0.4rem 0.4rem 0; font-size: 0.9rem; } /* ── Endpoint header ───────────────────────────────────────────────── */ .api-docs-eyebrow-row { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.4rem; } .api-docs-eyebrow-dot { width: 0.2rem; height: 0.2rem; border-radius: 9999px; background: var(--color-base-300); } .api-docs-eyebrow-path { font-family: var(--api-mono-font); font-size: 0.78rem; background: transparent; padding: 0; color: var(--color-base-content); opacity: 0.7; } .api-docs-endpoint-title { font-size: 1.2rem; font-weight: 600; margin: 0 0 0.5rem; } /* ── HTTP method tags ──────────────────────────────────────────────── */ .api-docs-method { display: inline-flex; align-items: center; font-family: var(--api-mono-font); font-size: 0.625rem; font-weight: 700; letter-spacing: 0.05em; padding: 0.05rem 0.45rem; border-radius: 0.4rem; border: 1px solid currentColor; background: color-mix(in oklab, currentColor 10%, transparent); } .api-docs-method.is-get { color: oklch(72% 0.15 160); } .api-docs-method.is-post { color: oklch(70% 0.13 230); } .api-docs-method.is-put { color: oklch(78% 0.13 75); } .api-docs-method.is-patch { color: oklch(78% 0.13 75); } .api-docs-method.is-delete { color: oklch(70% 0.18 25); } .api-docs-method.is-zinc { color: var(--color-base-content); opacity: 0.6; } /* ── Code blocks ───────────────────────────────────────────────────── */ .api-docs-code { margin: 0; border: 1px solid color-mix(in oklab, var(--color-neutral) 50%, transparent); border-radius: 0.7rem; overflow: hidden; background: var(--color-neutral); color: var(--color-neutral-content); } .api-docs-code-caption { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; padding: 0.5rem 0.85rem; background: color-mix(in oklab, var(--color-neutral) 80%, black 20%); border-bottom: 1px solid color-mix(in oklab, var(--color-neutral-content) 15%, transparent); font-size: 0.78rem; } .api-docs-code-title { color: var(--color-neutral-content); font-weight: 600; } .api-docs-code-meta { display: inline-flex; align-items: center; gap: 0.5rem; } .api-docs-code-meta code { font-family: var(--api-mono-font); font-size: 0.72rem; background: transparent; color: color-mix(in oklab, var(--color-neutral-content) 70%, transparent); padding: 0; } .api-docs-pre { margin: 0; padding: 0.95rem 1rem; font-family: var(--api-mono-font); font-size: 0.78rem; line-height: 1.55; overflow-x: auto; color: var(--color-neutral-content); background: transparent; } .api-docs-pre code { background: transparent; padding: 0; color: inherit; font-size: inherit; white-space: pre; } /* ── Properties list ──────────────────────────────────────────────── */ .api-docs-properties { margin: 0.5rem 0 1rem; border-top: 1px solid var(--color-base-200); } .api-docs-property { padding: 0.65rem 0; border-bottom: 1px solid var(--color-base-200); } .api-docs-property dt { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.15rem; font-size: 0.85rem; } .api-docs-property dd { margin: 0; font-size: 0.9rem; opacity: 0.85; } .api-docs-property-name { font-family: var(--api-mono-font); font-weight: 600; background: transparent; padding: 0; color: var(--color-base-content); } .api-docs-property-type { font-family: var(--api-mono-font); font-size: 0.72rem; color: var(--color-base-content); opacity: 0.6; } .api-docs-property-required { font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: oklch(70% 0.18 25); } /* Allow map interaction through non-content parts of Leaflet popups */ .leaflet-popup { pointer-events: none; } .leaflet-popup-content-wrapper, .leaflet-popup-tip, .leaflet-popup-close-button { pointer-events: auto; } /* Rover-page station + home label tooltips */ .rover-station-label, .rover-home-label { background: rgba(255, 255, 255, 0.92); border: none; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25); color: #0f172a; font-size: 10px; font-weight: 600; padding: 1px 4px; border-radius: 3px; white-space: nowrap; } .rover-station-label::before, .rover-home-label::before { display: none; } /* This file is for your main application CSS */