/* =========================================================================
   6-apps — the per-app styles: layout and structure carried over from the
   CDE build, redrawn flat. No bevels, no Style Manager (retired with the
   desktop), and no outlines: blocks are separated by fill, and the only
   boxes still drawn on the site are form fields and buttons.
   ========================================================================= */

/* ---- fileshare --------------------------------------------------------- */

.fs-controls {
  display: flex;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
  flex-wrap: wrap;
  align-items: center;
}
.fs-controls input, .fs-controls select { width: auto; flex: 0 1 14rem; }
.fs-name { max-width: 360px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- guestbook --------------------------------------------------------- */

.guestbook-list { display: flex; flex-direction: column; gap: var(--sp-3); }
.guestbook-entry {
  background: var(--bg-card);
  border-left: 3px solid var(--accent);
  padding: var(--sp-2) var(--sp-3);
}
.guestbook-entry-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-2);
  margin-bottom: var(--sp-1);
}
.guestbook-entry-name { color: var(--accent-dark); font-weight: 700; }
.guestbook-entry-date {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  white-space: nowrap;
}
.guestbook-entry-msg { white-space: pre-wrap; word-break: break-word; }

/* ---- blogs ------------------------------------------------------------- */

.blog-list { display: flex; flex-direction: column; gap: var(--sp-4); }
.blog-card-title { font-size: var(--fs-lg); margin-bottom: var(--sp-1); }
.blog-card-title a { color: var(--text-color); text-decoration: none; }
.blog-card-title a:hover { color: var(--accent); text-decoration: underline; }
.blog-card-blurb { color: var(--text-muted); margin-bottom: var(--sp-2); }
.blog-card-meta, .blog-post-meta {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  margin: 0;
}
.blog-post-header {
  padding-bottom: var(--sp-3);
  margin-bottom: var(--sp-4);
  border-bottom: 1px solid var(--border-color);
}
.blog-post-title { font-size: var(--fs-2xl); color: var(--accent-dark); margin-bottom: var(--sp-2); }
.blog-post-blurb { color: var(--text-muted); font-style: italic; margin-bottom: var(--sp-2); }
.blog-post-content { line-height: 1.75; margin-bottom: var(--sp-5); }
.blog-post-content h2 { margin-top: var(--sp-5); }
.blog-post-content h3 { margin-top: var(--sp-4); }
.blog-post-content a { text-decoration: underline; }
.blog-post-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-5);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--border-color);
  font-size: var(--fs-sm);
}
.blog-sentinel {
  text-align: center;
  color: var(--text-muted);
  padding: var(--sp-4);
  font-size: var(--fs-sm);
  font-style: italic;
}

/* ---- linklist ---------------------------------------------------------- */

.glink-meta {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  white-space: nowrap;
}

/* ---- auth / account ---------------------------------------------------- */

.social-login {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
}
.email-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg-card);
  margin-bottom: var(--sp-1);
  cursor: pointer;
  font-size: var(--fs-sm);
}
.email-row .email-addr {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--font-mono);
}
.account-actions { display: flex; gap: var(--sp-2); margin-top: var(--sp-4); flex-wrap: wrap; }
.account-actions button, .account-actions .btn { flex: 1; }
.auth-note {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  text-align: center;
  padding: var(--sp-3);
  margin-bottom: var(--sp-4);
  background: var(--bg-card);
}

/* ---- sitemap ----------------------------------------------------------- */

.sitemap-table { margin-bottom: var(--sp-5); }
.sitemap-table .st-path {
  white-space: nowrap;
  width: 1%;
  font-family: var(--font-mono);
}
.sitemap-table .st-path a { color: var(--accent-dark); font-weight: 700; }
.sitemap-table .st-label {
  white-space: nowrap;
  width: 1%;
  color: var(--accent);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.sitemap-table .st-desc { color: var(--text-muted); }
@media (max-width: 600px) {
  .sitemap-table .st-label { display: none; }
}

/* ---- 404 --------------------------------------------------------------- */

.error-page { text-align: center; padding: var(--sp-6) var(--sp-4); }
.error-page h1 { font-size: var(--fs-3xl); margin-bottom: var(--sp-3); }
.error-page img { margin: var(--sp-4) auto; display: block; max-width: 100%; }
.error-page .error-code { font-size: var(--fs-3xl); line-height: 1; margin-bottom: var(--sp-3); }

/* ---- shared app furniture ------------------------------------------------ */

.cde-toolbar {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  margin-bottom: var(--sp-4);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--border-color);
}
.cde-toolbar > :last-child { margin-left: auto; }

/* ---- llmmanager: API key page ------------------------------------------- */

.key-reveal { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.key-reveal code { flex: 1; min-width: 0; overflow-wrap: anywhere; }

/* ---- image tools --------------------------------------------------------- */

/* The drop target is the one place a boundary still matters, so it is
   drawn as a fill that changes on hover rather than as an outline. */
.it-source { padding: var(--sp-4); margin-bottom: var(--sp-4); background: var(--bg-card); }
.it-source.is-dropping { background: color-mix(in srgb, var(--accent) 18%, var(--bg-card)); }
.it-source .form-group:last-of-type { margin-bottom: var(--sp-2); }
.it-hint { font-size: var(--fs-sm); color: var(--text-muted); margin: 0; }
.it-source [data-it-url] { flex: 1 1 18rem; min-width: 0; }

.it-meta { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--text-muted); }

.it-preview {
  padding: var(--sp-2);
  margin-bottom: var(--sp-4);
  overflow: auto;
  max-height: 60vh;
  background: var(--bg-card);
}
.it-preview canvas { display: block; margin: 0 auto; image-rendering: pixelated; }

.it-note { font-size: var(--fs-sm); color: var(--text-muted); }

.it-controls {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  align-items: flex-end;
  padding-bottom: var(--sp-3);
  margin-bottom: var(--sp-4);
  border-bottom: 1px solid var(--border-color);
}
.it-controls input[type="color"] { width: 3.5rem; height: 2rem; padding: 2px; background-color: #fff; }
.it-controls input[type="range"] { width: 9rem; }

.it-compare {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  margin-bottom: var(--sp-4);
}
.it-figure { margin: 0; }
.it-figure > div { padding: var(--sp-2); display: flex; justify-content: center; background: var(--bg-card); }
.it-figure canvas { display: block; max-width: 100%; height: auto; image-rendering: pixelated; }
.it-figure figcaption {
  margin-top: var(--sp-1);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
}

/* ---- dashboards: llmdashboard + devicedash -------------------------------
   These two pages used to live in a separate full-screen instrument
   cluster (css/lcd.css). They are ordinary site pages now, so everything
   below is drawn from the kit's tokens and follows the kit's one rule:
   a border means "you can operate this", so nothing here is boxed —
   cards, meters and readouts separate themselves with a fill.

   Only devicedash's per-device binnacle still uses the cluster. */

/* The polling stamp that sits under the page title. */
.dash-status {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

/* Grades the kit's .cde-meter fill by magnitude. The bar is a single
   fill rather than the cluster's per-segment colouring, so the whole bar
   changes at the threshold — there are no segments here to colour. */
.cde-meter-fill.is-warn { background: var(--warning); }
.cde-meter-fill.is-crit { background: var(--error); }

/* ---- dashboard cards ----------------------------------------------------
   One card per slot / per device. auto-fit lands on two columns at the
   site's 820px measure and collapses to one on a phone. */
.dash-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}

.dash-card {
  background: var(--bg-card);
  border-radius: var(--radius);
  padding: var(--sp-3);
}
/* Device cards are links; strip the link ink so the card reads as a
   surface and let the fill carry the hover instead of an underline. */
a.dash-card {
  display: block;
  color: var(--text-color);
  text-decoration: none;
}
a.dash-card:hover { background: var(--bg-row-alt); }
a.dash-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dash-card.is-offline { opacity: 0.55; }

.dash-card-head {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  flex-wrap: wrap;
  margin-bottom: var(--sp-2);
}
.dash-card-name { font-weight: 700; color: var(--accent-dark); }
.dash-card-head .cde-badge { margin-left: auto; }

/* label / bar / figure. The bar is the reading; the number confirms it,
   so it is a fixed-width mono column and never reflows the bar. */
.dash-stat {
  display: grid;
  grid-template-columns: 4.5em 1fr 5.5em;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-xs);
  margin-bottom: var(--sp-1);
}
.dash-stat-label { color: var(--text-muted); }
.dash-stat-value { font-family: var(--font-mono); text-align: right; }

.dash-foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-3);
  margin-top: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

/* Key/value pairs inside a card, where a table's rules would be louder
   than the card itself. */
.dash-kv {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0 var(--sp-2);
  font-size: var(--fs-xs);
  margin-bottom: var(--sp-2);
}
.dash-kv dt { color: var(--text-muted); }
.dash-kv dd { margin: 0; font-family: var(--font-mono); text-align: right; }

/* ---- charts -------------------------------------------------------------
   Chart.js is told maintainAspectRatio:false, so it sizes to its parent
   and the parent has to carry the height. */
.dash-charts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.dash-chart {
  background: var(--bg-card);
  border-radius: var(--radius);
  padding: var(--sp-2);
}
.dash-chart-label {
  display: block;
  font-size: var(--fs-xs);
  color: var(--text-muted);
  margin-bottom: var(--sp-1);
}
.dash-chart-canvas { position: relative; height: 110px; }

/* ---- request log --------------------------------------------------------
   Eight columns will not fit the site's measure, so .cde-table-wrap
   scrolls them and the two prose columns are clamped rather than allowed
   to set the table's width. */
.dash-log tbody tr { cursor: pointer; }
.dash-log tbody tr:hover td,
.dash-log tbody tr:focus-visible td {
  background: color-mix(in srgb, var(--accent) 14%, var(--bg-card));
}
.dash-log td, .dash-log th { white-space: nowrap; }
.dash-cell-text {
  max-width: 18ch;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- request detail dialog ----------------------------------------------
   The kit has no modal. This is the only one on the site: a scrim plus a
   panel that is a card, opened by toggling .is-open. */
.dash-modal-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 50;
  padding: var(--sp-4);
  background: color-mix(in srgb, var(--bg-color) 82%, transparent);
}
.dash-modal-backdrop.is-open { display: flex; align-items: center; justify-content: center; }
.dash-modal {
  background: var(--bg-card);
  border-radius: var(--radius);
  padding: var(--sp-4);
  width: min(48rem, 100%);
  max-height: 88vh;
  display: flex;
  flex-direction: column;
}
.dash-modal-head {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}
.dash-modal-head h2 { margin: 0; }
.dash-modal-head .btn { margin-left: auto; }
.dash-modal-body { overflow-y: auto; flex: 1; }
.dash-modal-actions { margin-top: var(--sp-3); }
/* Prompt and completion text: pre already carries the card fill, this
   only stops a long transcript from pushing the dialog off-screen. */
.dash-detail-text { max-height: 30vh; overflow: auto; white-space: pre-wrap; word-break: break-word; }
