/* Boxes'n'Lines shared visual language, ported from boxesnlines.com's Tailwind config/index.css
   into plain CSS custom properties (this site isn't using Tailwind). Keep values in sync with
   that site's tailwind.config.js if it changes. */
:root {
  --surface-base: #1a1a2e;
  --surface-card: #16213e;
  --surface-deep: #0f0f1a;
  --border-default: #374151;
  --text-primary: #ffffff;
  --text-muted: #9ca3af;
  --accent-cyan: #1ba1e2;
  --accent-cyan-hover: #0080c0;
  --accent-green: #008a00;
  --accent-green-hover: #005700;
  --accent-orange: #f0a30a;
  --accent-orange-hover: #bd7000;
  --accent-yellow: #e3c800;
  --accent-magenta: #d80073;
  --status-success: #008a00;
  --status-error: #e51400;
  --status-warning: #f0a30a;
  --radius-btn: 0.375rem;
  --radius-card: 0.5rem;
  --shadow-card: 0 4px 6px -1px rgba(0, 0, 0, 0.3);
  --max-page: 1200px;
  --max-content: 960px;
  --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "Roboto Mono", ui-monospace, "SFMono-Regular", monospace;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--surface-deep);
  color: var(--text-primary);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

a {
  color: var(--accent-cyan);
  transition: color 0.2s;
}

a:hover {
  color: var(--accent-cyan-hover);
}

.page {
  max-width: var(--max-page);
  margin: 0 auto;
  padding: 0 1rem;
}

.content {
  max-width: var(--max-content);
  margin: 0 auto;
  padding: 0 1rem;
}

header.site-header {
  background: var(--surface-base);
  border-bottom: 1px solid var(--border-default);
}

header.site-header .page {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 1rem;
  padding-bottom: 1rem;
}

header.site-header .brand {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--text-primary);
  text-decoration: none;
}

header.site-header .brand:hover {
  color: var(--text-primary);
}

header.site-header .brand-pictograph {
  height: 1.75rem;
  width: 1.75rem;
}

header.site-header .brand-logo {
  height: 1.5rem;
  width: auto;
}

header.site-header .brand-tagline {
  padding-left: 0.75rem;
  margin-left: 0.25rem;
  border-left: 1px solid var(--border-default);
  font-size: 0.8125rem;
  font-weight: 400;
  color: var(--text-muted);
  white-space: nowrap;
}

@media (max-width: 900px) {
  header.site-header .brand-tagline {
    display: none;
  }
}

header.site-header nav a {
  color: var(--text-muted);
  text-decoration: none;
  margin-left: 1.5rem;
  font-size: 0.95rem;
}

header.site-header nav a:hover {
  color: var(--text-primary);
}

footer.site-footer {
  background: var(--surface-base);
  border-top: 1px solid var(--border-default);
  margin-top: 3rem;
}

footer.site-footer .page {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  align-items: center;
  justify-content: space-between;
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
}

@media (min-width: 768px) {
  footer.site-footer .page {
    flex-direction: row;
  }
}

footer.site-footer p {
  color: var(--text-muted);
  font-size: 0.875rem;
  margin: 0;
}

main {
  flex: 1 0 auto;
}

/* Forms */
.field {
  margin-bottom: 1.25rem;
}

.field label {
  display: block;
  margin-bottom: 0.25rem;
  font-size: 0.875rem;
  color: var(--text-muted);
}

.field .required {
  color: var(--status-error);
}

.input {
  width: 100%;
  border-radius: var(--radius-btn);
  border: 1px solid var(--border-default);
  background: var(--surface-deep);
  color: var(--text-primary);
  padding: 0.75rem 1rem;
  font-family: inherit;
  font-size: 1rem;
  transition: border-color 0.2s, box-shadow 0.2s;
}

.input::placeholder {
  color: var(--text-muted);
  opacity: 0.6;
}

.input:focus {
  outline: none;
  border-color: var(--accent-cyan);
  box-shadow: 0 0 0 1px var(--accent-cyan);
}

.field-error {
  margin-top: 0.25rem;
  font-size: 0.75rem;
  color: var(--status-error);
}

.form-banner {
  border-radius: var(--radius-btn);
  padding: 0.75rem 1rem;
  font-size: 0.875rem;
  margin-bottom: 1.25rem;
}

.form-banner.error {
  background: rgba(229, 20, 0, 0.1);
  color: var(--status-error);
}

.form-banner.success {
  background: rgba(0, 138, 0, 0.1);
  color: var(--status-success);
}

/* Buttons */
.btn {
  display: inline-block;
  border-radius: var(--radius-btn);
  padding: 0.75rem 1.5rem;
  font-weight: 600;
  font-size: 1rem;
  border: none;
  cursor: pointer;
  text-decoration: none;
  text-align: center;
  transition: background-color 0.2s, opacity 0.2s;
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-primary {
  background: var(--accent-green);
  color: #ffffff;
}

.btn-primary:hover:not(:disabled) {
  background: var(--accent-green-hover);
  color: #ffffff;
}

/* Auth pages */
.auth-card {
  max-width: 26rem;
  margin: 3rem auto;
  background: var(--surface-card);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 2rem;
}

.auth-card h1 {
  font-size: 1.5rem;
  margin: 0 0 1.5rem;
}

.auth-card .auth-links {
  margin-top: 1.5rem;
  font-size: 0.875rem;
  color: var(--text-muted);
  text-align: center;
}

/* Homepage */
.hero {
  text-align: center;
  padding: 2rem 1rem 2rem;
}

.hero h1 {
  font-size: 2.5rem;
  margin: 0 0 1rem;
}

.hero p {
  color: var(--text-muted);
  font-size: 1.125rem;
  max-width: 40rem;
  margin: 0 auto 2rem;
}

.hero .btn {
  margin: 0 0.5rem;
}

.feature-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1.5rem;
  margin-top: 1rem;
}

.feature-card {
  background: var(--surface-card);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 1.5rem;
}

.feature-card h2,
.feature-card h3 {
  margin: 0 0 0.5rem;
  font-size: 1.0625rem;
}

.feature-card p {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.9375rem;
  line-height: 1.6;
}

/* Dashboard: API keys */
.code-block {
  border-radius: var(--radius-btn);
  border: 1px solid var(--border-default);
  background: var(--surface-deep);
  color: var(--text-primary);
  padding: 0.75rem 1rem;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
  overflow-x: auto;
}

.key-reveal {
  margin-top: 0.5rem;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius-btn);
  background: var(--surface-deep);
  font-family: var(--font-mono);
  font-size: 0.875rem;
  overflow-wrap: break-word;
}

.key-table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 2rem;
}

.key-table th,
.key-table td {
  text-align: left;
  padding: 0.6rem 0.75rem;
  border-bottom: 1px solid var(--border-default);
  font-size: 0.875rem;
}

.key-table th {
  color: var(--text-muted);
  font-weight: 600;
}

/* Playground (/app, /demo) */
.playground {
  padding-top: 2rem;
  padding-bottom: 3rem;
}

.playground-hint {
  color: var(--text-muted);
  margin-bottom: 1.5rem;
}

.playground-textarea {
  height: 14rem;
  resize: vertical;
  font-family: var(--font-mono);
  font-size: 0.875rem;
  line-height: 1.5;
}

/* Playground result: diagram on top, code below - the two-way click-to-navigate view */
.playground-result {
  margin-top: 2rem;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.playground-result[hidden] {
  display: none;
}

.diagram-pane {
  height: 28rem;
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-btn);
  border: 1px solid var(--border-default);
  background: var(--surface-deep);
}

.diagram-pane svg {
  width: 100%;
  height: 100%;
}

.diagram-download-btn {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  z-index: 2;
  border-radius: var(--radius-btn);
  border: 1px solid var(--border-default);
  background: rgba(26, 26, 46, 0.85);
  color: var(--text-primary);
  font-size: 0.8125rem;
  font-weight: 600;
  padding: 0.4rem 0.75rem;
  cursor: pointer;
  transition: background-color 0.2s, opacity 0.2s;
}

.diagram-download-btn:hover {
  background: var(--surface-deep);
}

.code-pane {
  max-height: 20rem;
  overflow: auto;
  border-radius: var(--radius-btn);
  border: 1px solid var(--border-default);
  background: var(--surface-deep);
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  line-height: 1.6;
  padding: 0.5rem 0;
}

.code-line {
  display: flex;
  padding: 0 1rem;
  cursor: pointer;
}

.code-line:hover {
  background: rgba(255, 255, 255, 0.05);
}

.code-line.pg-active {
  background: rgba(0, 255, 0, 0.15);
}

.code-line-number {
  flex: 0 0 3rem;
  margin-right: 1rem;
  text-align: right;
  color: var(--text-muted);
  user-select: none;
}

.code-line-text {
  white-space: pre;
}

.node.pg-clickable {
  cursor: pointer;
}

/* A node with fill:none (a Decision diamond, a subquery/loop frame) only registers clicks on its
   painted stroke/text by default - pointer-events:visiblePainted treats the unfilled interior as
   not there. Forcing pointer-events:all makes the whole shape's area clickable regardless of
   whether it actually has a fill. */
.node.pg-clickable path,
.node.pg-clickable polygon,
.node.pg-clickable rect,
.node.pg-clickable circle,
.node.pg-clickable ellipse {
  pointer-events: all;
}

/* !important: overrides mermaid's own <style> block embedded inside the rendered SVG, which
   otherwise wins on specificity for the classDef-driven fill/stroke rules. Scoped to the shape
   elements specifically, not the label - but NOT via a direct-child (>) combinator: some shapes
   (stadium ones like Start/End/RAISERROR) wrap their actual <path> inside an extra
   <g class="basic label-container outer-path">, so it's a grandchild of .node, not a direct
   child, and > silently failed to match it (confirmed via the live DOM). A plain descendant
   selector matches at any depth instead; the only other path/rect it could match is the label's
   own zero-size placeholder <rect> (no visible fill/stroke to begin with, so harmless). */
.node.pg-active path,
.node.pg-active polygon,
.node.pg-active rect,
.node.pg-active circle,
.node.pg-active ellipse {
  stroke: #00ff00 !important;
  stroke-width: 3px !important;
  filter: drop-shadow(0 0 6px #00ff00) drop-shadow(0 0 12px #00ff00);
}

/* Mermaid's own embedded <style> block sets edge strokes assuming a light page background, so
   they read as barely-visible dark lines against this app's dark diagram-pane background -
   !important is needed to win over that embedded block, same as the .pg-active override above. */
.diagram-pane .edgePath path,
.diagram-pane path.flowchart-link {
  stroke: var(--text-muted) !important;
  stroke-width: 1.5px !important;
}

.diagram-pane .edgePath .arrowheadPath,
.diagram-pane marker path {
  fill: var(--text-muted) !important;
  stroke: var(--text-muted) !important;
}

/* The vendored svg-pan-zoom library only ships default styling for the outer .svg-pan-zoom-control
   wrapper; the actual visible shapes are its child .svg-pan-zoom-control-background rect (a
   translucent white box, unmodified from the library default) and .svg-pan-zoom-control-element
   path (the icon glyph itself, which has no fill of its own and inherits from its parent) - fill
   inherited from the wrapper alone was never enough contrast against the dark background. */
.svg-pan-zoom-control {
  fill: #cbd5e1 !important;
  opacity: 0.85;
}

.svg-pan-zoom-control-background {
  fill: #1a1a2e !important;
  fill-opacity: 0.85 !important;
  stroke: #cbd5e1;
  stroke-opacity: 0.4;
}

.svg-pan-zoom-control-element {
  fill: #cbd5e1 !important;
}

.svg-pan-zoom-control:hover {
  opacity: 1;
}

/* Full-bleed pages (currently just /demo): the page fills the viewport under the header with no
   page-level scrollbar - main becomes a flex column so a full-bleed page's own content can opt
   into flex:1 to claim exactly the remaining space, rather than guessing at a calc(100vh - Npx)
   header height. Ordinary pages are untouched, since main's default (non-flex) block layout only
   changes for a single flex item here anyway. */
body.page-full-bleed {
  height: 100vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

body.page-full-bleed main {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* The demo page: diagram-pane and code-pane should get as much of the viewport as possible with
   no scrollbars of their own making - so, unlike the fixed-height panes App.cshtml still uses,
   these flex to fill whatever's left after the intro text/textarea/button above them. */
.playground-demo {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}

.playground-demo .playground-intro {
  margin-bottom: 0.5rem;
}

.playground-demo .playground-intro h1 {
  margin: 0 0 0.25rem;
  font-size: 1.25rem;
}

.playground-demo .playground-hint {
  margin-bottom: 0;
  font-size: 0.8125rem;
}

/* The diagram/code panes only ever show briefly on the way into full screen mode (see demo.js) -
   returning from full screen hides them entirely rather than sharing the page with them, so the
   entry box itself is free to use all the space that's left after the intro text, rather than
   deliberately leaving room for panes that (in practice) are never shown alongside it. */
.playground-demo .field {
  flex: 1 1 auto;
  min-height: 0;
  margin-bottom: 0.5rem;
  display: flex;
  flex-direction: column;
}

.playground-demo .field label {
  flex: 0 0 auto;
}

.playground-demo .playground-textarea {
  flex: 1 1 auto;
  min-height: 0;
  height: auto;
}

.playground-demo .playground-result {
  flex: 1 1 auto;
  min-height: 0;
  margin-top: 0.5rem;
}

.playground-demo .diagram-pane,
.playground-demo .code-pane {
  flex: 1 1 0;
  min-height: 0;
  height: auto;
}

/* Groups the "exit full screen" button and the diagram pane's own download button into one fixed
   top-right cluster once full screen is active, so the two sit side by side instead of the
   download button's own top-right placement inside .diagram-pane landing right underneath this
   one - .diagram-download-btn is appended in here (not the diagram pane) for /demo specifically,
   see playground.js's toolbarEl parameter. */
.fullscreen-toolbar {
  display: none;
  position: fixed;
  top: 1rem;
  right: 1rem;
  z-index: 1000;
  gap: 0.5rem;
  align-items: center;
}

body.demo-fullscreen .fullscreen-toolbar {
  display: flex;
}

/* Only shown once full screen mode is actually active (entered automatically after generating a
   diagram, not via a manual "enter full screen" button) - its only job here is to exit again. */
.fullscreen-toggle {
  border: 1px solid var(--border-default);
  border-radius: var(--radius-btn);
  background: rgba(22, 33, 62, 0.85);
  color: var(--text-primary);
  padding: 0.5rem 0.9rem;
  font-size: 0.8125rem;
  cursor: pointer;
}

.fullscreen-toggle:hover {
  background: var(--surface-card);
}

/* Inside the toolbar, the download button is a normal flex child rather than absolutely
   positioned against .diagram-pane (which it isn't nested in when rendered here). */
.fullscreen-toolbar .diagram-download-btn {
  position: static;
}

/* Full screen mode: hide everything but the diagram/code panes themselves, so they get the
   entire viewport rather than just whatever main leaves over. */
body.demo-fullscreen header.site-header {
  display: none;
}

body.demo-fullscreen .playground-demo {
  /* .page (shared with every other page) caps width at --max-page and centers with auto margins -
     full screen means the panes should claim the entire viewport width too, not just its height. */
  max-width: none;
  width: 100%;
  margin: 0;
  padding: 0;
}

body.demo-fullscreen .playground-demo .playground-intro,
body.demo-fullscreen .playground-demo .form-banner,
body.demo-fullscreen .playground-demo .field,
body.demo-fullscreen .playground-demo #demo-generate {
  display: none;
}

body.demo-fullscreen .playground-demo .playground-result {
  margin-top: 0;
}

body.demo-fullscreen .playground-demo .diagram-pane,
body.demo-fullscreen .playground-demo .code-pane {
  border-radius: 0;
}
