/* sessionbin — custom stylesheet */

/* Reset */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* Restated because any author rule setting display, such as the one on buttons below,
   beats the browser's own [hidden] rule and leaves the element on screen. */
[hidden] { display: none; }

/* Variables — Light (default) */
:root {
  --sb-bg: #fafaf8;
  --sb-surface: #fff;
  --sb-text: #18181b;
  --sb-muted: #71717a;
  --sb-border: #e4e4e7;
  --sb-accent: #00b85c;
  --sb-accent-hover: #009e4f;
  --sb-danger: #dc2626;
  --sb-danger-hover: #b91c1c;
  --sb-code-bg: #f4f4f5;
  --sb-focus-ring: rgba(0, 210, 106, 0.25);
}

/* Variables — Dark */
[data-theme="dark"] {
  --sb-bg: #1a1a1e;
  --sb-surface: #242428;
  --sb-text: #e0e0e4;
  --sb-muted: #a1a1aa;
  --sb-border: #333338;
  --sb-accent: #00d26a;
  --sb-accent-hover: #33e08a;
  --sb-danger: #f87171;
  --sb-danger-hover: #fca5a5;
  --sb-code-bg: #2a2a2e;
  --sb-focus-ring: rgba(0, 210, 106, 0.25);
}

/* Base */
html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }

body {
  font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--sb-text);
  background: var(--sb-bg);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* Typography */
h1, h2, h3 { font-weight: 500; line-height: 1.3; }
h1 { font-size: 1.25rem; margin-bottom: 0.5rem; }
h2 { font-size: 1.125rem; margin-bottom: 0.5rem; }
h3 { font-size: 1rem; margin-bottom: 0.375rem; }
p { margin-bottom: 0.75rem; }

code, pre, kbd, .mono {
  font-family: 'JetBrains Mono', ui-monospace, 'Cascadia Code', 'Fira Code', Menlo, Consolas, monospace;
}

a { color: var(--sb-accent); text-decoration: none; }
a:hover { text-decoration: underline; }

small { font-size: 0.75rem; color: var(--sb-muted); }

/* Layout */
/* width is explicit because body is a flex column: auto side margins beat
   align-items: stretch, so without it every container shrinks to fit-content. */
.container {
  width: 100%;
  max-width: 1100px;
  margin: 0 auto;
  padding-left: 1.25rem;
  padding-right: 1.25rem;
}

/* Pushes the footer down when the content is shorter than the viewport. */
main.container { flex: 1 0 auto; }

/* With no footer configured, the content would otherwise end at the page edge. */
main.container:not(:has(~ footer)) { padding-bottom: 4rem; }

/* Navigation */
nav.container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--sb-border);
  margin-bottom: 1.5rem;
}

.brand {
  font-weight: 500;
  font-size: 0.9375rem;
  color: var(--sb-accent);
  text-decoration: none;
}
.brand:hover { text-decoration: none; }

.nav-icons {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.nav-icon {
  color: var(--sb-muted);
  display: flex;
  align-items: center;
  padding: 0.25rem;
  border-radius: 4px;
  text-decoration: none;
}
.nav-icon:hover { color: var(--sb-text); text-decoration: none; }

#theme-toggle { background: none; border: none; cursor: pointer; }

/* Which glyph shows is a fact about the theme, like any colour here, so it is settled in
   the same style pass as the palette rather than by script afterwards. Set from JS it
   would also mean both glyphs paint until the script at the foot of the page runs. */
.icon-sun { display: none; }
[data-theme="dark"] .icon-sun { display: block; }
[data-theme="dark"] .icon-moon { display: none; }

/* Footer */
footer.container {
  padding: 1.5rem 1.25rem 1rem;
  text-align: center;
  font-size: 0.75rem;
  color: var(--sb-muted);
  border-top: 1px solid var(--sb-border);
  margin-top: 2rem;
}

/* A drawn rule rather than a glyph: the postamble ends in a period, and a middot or
   bullet sitting next to it reads as stray punctuation. */
footer.container > *:not(:last-child)::after {
  content: "";
  display: inline-block;
  width: 1px;
  height: 0.8em;
  background: currentColor;
  opacity: 0.3;
  margin: 0 0.7rem;
  vertical-align: -0.08em;
}

/* Stack instead of wrapping, which would strand the rule at the end of a line. */
@media (max-width: 30rem) {
  footer.container > * { display: block; }
  footer.container > *:not(:last-child)::after { display: none; }
}

/* Buttons */
button, .btn {
  display: inline-block;
  padding: 0.5rem 1rem;
  font-family: inherit;
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.4;
  color: #fff;
  background: var(--sb-accent);
  border: 1px solid var(--sb-accent);
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
button:hover, .btn:hover {
  background: var(--sb-accent-hover);
  border-color: var(--sb-accent-hover);
  /* An anchor styled as a button still matches a:hover, which would underline it. */
  text-decoration: none;
}

/* Dropzone */
#dropzone {
  border: 2px dashed var(--sb-border);
  border-radius: 6px;
  padding: 1.5rem;
  text-align: center;
  cursor: pointer;
  margin: 1rem 0;
  transition: border-color 0.15s, background 0.15s;
}
#dropzone.dragging {
  border-color: var(--sb-accent);
  background: var(--sb-focus-ring);
}
#dropzone.has-file { border-color: var(--sb-accent); }
#dropzone.has-file p { color: var(--sb-text); font-size: 1rem; }
#dropzone p { margin: 0 0 0.5rem; color: var(--sb-muted); font-size: 0.8125rem; }
#dropzone input[type="file"] { display: none; }

/* Code blocks */
pre {
  background: var(--sb-code-bg);
  border: 1px solid var(--sb-border);
  border-radius: 4px;
  padding: 0.75rem 1rem;
  font-size: 0.8125rem;
  line-height: 1.5;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  margin-bottom: 0.75rem;
}

code {
  font-size: 0.8125rem;
}

:not(pre) > code {
  background: var(--sb-code-bg);
  padding: 0.125rem 0.375rem;
  border-radius: 3px;
}

/* Manage page */
.session-summary { font-size: 0.8125rem; color: var(--sb-muted); margin-bottom: 1.25rem; }

.share-block { margin-bottom: 1.75rem; }
.share-url { font-size: 0.9375rem; margin-bottom: 0.875rem; }

/* Facts list. One label column and one value column, so everything below the share link
   lines up on a single spine instead of each row inventing its own shape. */
dl {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.625rem 1rem;
  font-size: 0.8125rem;
  margin-bottom: 1.5rem;
}
dt { color: var(--sb-muted); font-weight: 500; }
/* anywhere, not break-word: only anywhere shrinks the min-content size, which is what
   lets the 1fr track narrow enough for a long URL to stop overflowing the page. */
dd { margin: 0; overflow-wrap: anywhere; }

.field-note { margin: 0.25rem 0 0; font-size: 0.75rem; color: var(--sb-muted); }

.delete-row { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; font-size: 0.8125rem; }
.btn-quiet {
  padding: 0.3rem 0.65rem;
  background: none;
  color: var(--sb-danger);
  border-color: var(--sb-border);
}
.btn-quiet:hover { background: var(--sb-danger); border-color: var(--sb-danger); color: #fff; }

/* Copy button */
/* anywhere, not break-word: a long URL has no break opportunity of its own, so only
   anywhere lets the flex item shrink below the URL's width on a narrow screen. */
.copyable-url { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem; overflow-wrap: anywhere; }
.btn-copy {
  flex: none;
  padding: 0 0.375rem;
  font-size: 0.6875rem;
  line-height: 1.6;
  background: var(--sb-code-bg);
  color: var(--sb-muted);
  border: 1px solid var(--sb-border);
}
/* background is restated because button:hover would otherwise win it back, being a
   heavier selector than .btn-copy. */
.btn-copy:hover { background: var(--sb-code-bg); color: var(--sb-text); }

/* Its own line, rather than a third column squeezing the URL on a narrow screen. It only
   takes one when a copy has failed: hidden, it is out of flow. */
.copy-status { flex-basis: 100%; font-size: 0.75rem; color: var(--sb-danger); }

/* Notices */
.notice {
  border-left: 3px solid var(--sb-border);
  padding: 0.75rem 1rem;
  font-size: 0.8125rem;
  margin: 1.5rem 0;
}
.notice--deleted { border-left-color: var(--sb-muted); color: var(--sb-muted); }


/* Errors */
.errors { color: var(--sb-danger); font-size: 0.8125rem; margin: 0.25rem 0; }

/* Upload row */
.upload-row { display: flex; align-items: center; gap: 0.75rem; }

/* CLI section */
.cli-section { margin-top: 2rem; }

/* Each subsection opens a new topic, so it gets air above it. The first one is the
   exception: it belongs to the h2 directly above it and reads as part of it. */
.cli-section h3 { margin-top: 1.75rem; }
.cli-section h2 + h3 { margin-top: 1rem; }

pre.shell span::before {
  content: "$ ";
  color: var(--sb-accent);
  user-select: none;
}

/* Copyable command block. The wrapper and the button are built by copy.js, so a block
   without JS is simply a block. */
.snippet { position: relative; }

/* Room kept clear so a command that wraps never runs under the button. */
.snippet pre.shell { padding-right: 2.25rem; }

/* A bare glyph, drawn like the navbar's icons rather than as a filled button. A
   background and a border would carry the 150ms transition every button here has for its
   hover, and that transition runs on a theme switch too: the button would sit there lit
   from the old palette for a moment after the page around it had turned over. Only
   colour changes here, and colour is not transitioned, so it keeps step. */
.btn-copy-icon {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  display: flex;
  padding: 0.25rem;
  color: var(--sb-muted);
  background: none;
  border: none;
  border-radius: 4px;
}
.btn-copy-icon:hover { color: var(--sb-text); background: none; }

/* After :hover, which the cursor is still inside the moment a copy succeeds. */
.btn-copy-icon.is-copied { color: var(--sb-accent); }

.snippet-label {
  font-size: 0.75rem;
  color: var(--sb-muted);
  margin: 0 0 0.25rem;
}

/* Harness tabs */
/* Scrolls rather than wraps: four harness names fit on a phone, a fifth would otherwise
   drop to a second row and split the underline the tabs sit on. */
.tab-list {
  display: flex;
  gap: 0.25rem;
  border-bottom: 1px solid var(--sb-border);
  margin-bottom: 1rem;
  overflow-x: auto;
}

.tab {
  padding: 0.5rem 0.75rem;
  color: var(--sb-muted);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  white-space: nowrap;
}
.tab:hover { color: var(--sb-text); background: none; border-color: transparent; }
.tab[aria-selected="true"] { color: var(--sb-text); border-bottom-color: var(--sb-accent); }

/* Tooltips
   Drawn rather than left to the browser's own title tooltip, which cannot be warmed:
   it waits about a second every time, however recently you read the last one. */
.tooltip {
  position: fixed;
  z-index: 60;
  padding: 0.2rem 0.45rem;
  border-radius: 4px;
  background: var(--sb-text);
  color: var(--sb-surface);
  font-family: 'JetBrains Mono', ui-monospace, Menlo, Consolas, monospace;
  font-size: 0.6875rem;
  line-height: 1.5;
  white-space: nowrap;
  max-width: calc(100vw - 1rem);
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
  opacity: 0;
  /* Leaving is immediate. A transition is read from the state being moved to, so this
     governs the way out and the rule below governs the way in. */
  transition: opacity 0ms;
}

.tooltip[data-show="true"] {
  opacity: 1;
  transition: opacity 120ms ease-out;
}

/* Warm: the reader is already reading tooltips, so fading in again only lags them. */
.tooltip[data-show="true"][data-instant="true"] { transition-duration: 0ms; }

@media (prefers-reduced-motion: reduce) {
  .tooltip[data-show="true"] { transition-duration: 0ms; }
}

/* Not found */
.notfound { text-align: center; padding: 4rem 0 3rem; }

.notfound-code {
  font-family: 'JetBrains Mono', ui-monospace, Menlo, Consolas, monospace;
  font-size: 4rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--sb-border);
}

.notfound h1 { font-size: 1.5rem; margin-top: 0.75rem; }

/* Utility */
.text-muted { color: var(--sb-muted); }

/* Read aloud, never shown. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
