/* My CastomAI panel (both dashboards) — only what castomo-dashkit does not already draw.
   Every value is a kit token; served as /shared/panel.css. */

/* The page's rhythm (dashkit GUIDELINES §0.18): a screen puts its blocks straight into #view, so one
   rule spaces them all — every block one gap below the one before. */
#view > * + * { margin-top: var(--gap); }
#view > * + .section { margin-top: var(--s5); }
.pre-line { white-space: pre-line; }
.muted { color: var(--ink-3); font-weight: 500; }
.noscript { padding: var(--s4); text-align: center; }

/* ---------- Sign in ---------- */
.auth-title { font-size: var(--t3); }
.auth-card > .stack-sm + * { margin-top: var(--s3); }
.auth-foot { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s0); }

/* ---------- App cards ---------- */
.app-card-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s0); margin-bottom: var(--s1); }
.app-mark { display: inline-grid; place-items: center; inline-size: 2.4rem; block-size: 2.4rem; border-radius: 50%; border: 2px solid var(--accent); color: var(--accent-ink); font-weight: 700; font-size: var(--t-1); }
.meter-block + .meter-block { margin-top: var(--s2); }
.meter-block meter { inline-size: 100%; }

/* ---------- Hosted editor and app runner ---------- */
/* The editor is an iframe that fills this box, so the box needs a height of its own. */
.editor-stage { block-size: calc(100dvh - 13rem); min-block-size: 32rem; border-radius: var(--radius-card); overflow: hidden; border: var(--rule-w) solid var(--rule); }

/* ---------- Built-in apps: tiles like castomai.com's app page ---------- */
/* Tiles pack densely (`dense`) so the big one never leaves a hole beside it (GUIDELINES §0.13). */
.bento { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-flow: dense; gap: var(--gap); }
.bento-tile { position: relative; display: block; min-block-size: 11rem; overflow: hidden; color: inherit; text-decoration: none; }
.bento-tile .card-title, .bento-tile .card-sub { position: relative; z-index: 1; max-inline-size: 62%; }
.bento-big { grid-column: span 2; grid-row: span 2; min-block-size: 22rem; }
.bento-big .card-title { font-size: var(--t3); }
.bento-art { position: absolute; inset-inline-end: 0; inset-block-end: 0; inline-size: 52%; max-block-size: 70%; pointer-events: none; }
.bento-big .bento-art { inline-size: 70%; max-block-size: 78%; }
.bento-tile:hover { border-color: var(--accent); }
.bento-out { position: absolute; inset-inline-end: var(--s1); inset-block-start: var(--s1); color: var(--ink-3); }
@media (max-width: 860px) { .bento { grid-template-columns: repeat(2, minmax(0, 1fr)); } .bento-big { grid-column: span 2; grid-row: span 1; min-block-size: 15rem; } }
@media (max-width: 520px) { .bento { grid-template-columns: minmax(0, 1fr); } .bento-big { grid-column: auto; } .bento-tile .card-title, .bento-tile .card-sub { max-inline-size: 70%; } }

/* ---------- Toolbar over a list ---------- */
.toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1); }
.toolbar .input, .toolbar .select { inline-size: auto; min-inline-size: 12rem; }
.project-tile .app-card-meta { margin-block: var(--s0); }

/* ---------- The apps drawer (right edge) ---------- */
.apps-drawer-handle { position: fixed; inset-inline-end: 0; inset-block-start: 40%; z-index: 30; }
.apps-drawer { position: fixed; inset-block: 0; inset-inline-end: 0; z-index: 40; inline-size: min(22rem, 92vw); display: flex; flex-direction: column; background: var(--paper); border-inline-start: var(--rule-w) solid var(--rule); box-shadow: var(--shadow-pop); transform: translateX(100%); transition: transform .2s ease; visibility: hidden; }
[dir="rtl"] .apps-drawer { transform: translateX(-100%); }
.apps-drawer[data-open] { transform: none; visibility: visible; }
.apps-drawer-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s1); padding: var(--s2); border-block-end: var(--rule-w) solid var(--rule); }
.apps-drawer-body { overflow: auto; padding: var(--s1) var(--s2) var(--s3); }
.apps-drawer h3 { margin-block: var(--s2) var(--s0); font-size: var(--t-1); color: var(--ink-3); text-transform: uppercase; letter-spacing: .04em; }
.apps-drawer .list > li { min-block-size: 44px; padding-block: 4px; }
.apps-drawer a.list-row { display: flex; align-items: center; gap: var(--s1); inline-size: 100%; color: inherit; text-decoration: none; }
.apps-drawer a.list-row:hover b { color: var(--accent-ink); }
@media (prefers-reduced-motion: reduce) { .apps-drawer { transition: none; } }

/* ---------- Headings over a block of tiles ---------- */
/* A section's heading needs air before its tiles: the heading is a label for the block, not part of its first row. */
.section > h2 { margin-block-end: var(--s3); }

/* ---------- Tiles come alive on hover ---------- */
/* Every tile — an app, a built-in app, a saved project, a workspace, a figure — lifts a little, gains
   its shadow and its accent edge, and a tile with a drawing lets the drawing lean in. Only where a
   pointer can hover, and never for someone who asked for less motion. `transform` and `box-shadow` only,
   so nothing reflows. */
.bento-tile, .app-card, .rt, .card.stat, .grid > .card:not(.stat) {
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out), border-color var(--dur) var(--ease);
}
.bento-art { transition: transform var(--dur-slow) var(--ease-spring); transform-origin: 85% 90%; }
.bento-tile .card-title { transition: color var(--dur) var(--ease); }
.app-mark { transition: transform var(--dur-slow) var(--ease-spring), background-color var(--dur) var(--ease); }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .bento-tile:hover, .app-card:hover, .rt:hover, .card.stat:hover, .grid > .card:not(.stat):hover { transform: translateY(-4px); box-shadow: var(--shadow-pop); border-color: color-mix(in oklab, var(--accent) 55%, var(--rule)); }
  .bento-tile:hover .bento-art, .bento-tile:focus-visible .bento-art { transform: scale(1.07) rotate(-2.5deg); }
  .bento-tile:hover .card-title { color: var(--accent-ink); }
  .app-card:hover .app-mark { transform: scale(1.12) rotate(-6deg); background: var(--accent-soft); }
  .bento-tile:active, .app-card:active, .rt:active { transform: translateY(-1px) scale(.995); }
}

/* ---------- Record tiles (Projects and entities) ---------- */
/* A tile is a small poster: a tinted cover with the entity's Noodle drawing, then what is inside.
   Tints come from the brand ramp (--brand-1..3), the two kinds one step apart, so a wall of tiles reads
   as one family with a rhythm rather than a grid of grey boxes. */
.rt { padding: 0; display: flex; flex-direction: column; overflow: hidden; position: relative; }
.rt-cover { position: relative; block-size: 7.75rem; overflow: hidden; background: var(--accent-soft); background: linear-gradient(125deg, color-mix(in oklab, var(--brand-1) 12%, var(--paper)) 0%, color-mix(in oklab, var(--brand-3) 24%, var(--paper)) 100%); background-size: 140% 140%; background-position: 0% 50%; transition: background-position .6s var(--ease-out); }
.rt[data-kind="project"] .rt-cover { background: linear-gradient(125deg, color-mix(in oklab, var(--brand-2) 14%, var(--paper)) 0%, color-mix(in oklab, var(--brand-1) 30%, var(--paper)) 100%); background-size: 140% 140%; }
/* A slow diagonal glint crosses the cover when the tile is hovered. */
.rt-cover::after { content: ""; position: absolute; inset: 0; background: linear-gradient(105deg, transparent 35%, color-mix(in oklab, var(--paper) 55%, transparent) 50%, transparent 65%); transform: translateX(-130%); pointer-events: none; }
.rt-art { position: absolute; inset-inline-end: 2%; inset-block-end: -16%; inline-size: 46%; max-block-size: 118%; transform-origin: 65% 90%; transition: transform var(--dur-slow) var(--ease-spring); pointer-events: none; }
.rt-kind { position: absolute; inset-block-start: var(--s1); inset-inline-start: var(--s1); z-index: 1; display: inline-flex; align-items: center; gap: 6px; padding: 4px 11px 4px 8px; border-radius: 999px; background: color-mix(in oklab, var(--paper) 78%, transparent); backdrop-filter: blur(6px); color: var(--accent-ink); font-size: var(--t-1); font-weight: 650; }
.rt-kind .ci { --ci-size: 15px; }

.rt-body { flex: 1; display: grid; align-content: start; gap: var(--s0); padding: var(--s2) var(--s2) var(--s1); }
.rt-title { font-size: 1.02rem; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* The whole tile is the click target: the title's button stretches over it, and the action buttons sit above. */
.rt-open { all: unset; cursor: pointer; }
.rt-open::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.rt:has(.rt-open:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.rt-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; color: var(--ink-3); font-size: var(--t-1); }
.rt-source { color: var(--ink-2); font-weight: 600; min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-inline-size: 60%; }
.app-mark-sm { inline-size: 1.4rem; block-size: 1.4rem; font-size: .62rem; border-width: 1.5px; }
.rt-excerpt { color: var(--ink-2); font-size: var(--t-1); line-height: 1.5; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.rt-chips { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; margin-block-start: 2px; }
.rt-chips li { display: inline-flex; gap: 6px; max-inline-size: 100%; padding: 3px 10px; border-radius: 999px; background: var(--field); color: var(--ink); font-size: var(--t-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rt-chips li span { color: var(--ink-3); }

.rt-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s1); padding: 0 var(--s2) var(--s2); min-block-size: 2.6rem; }
.rt-go { display: inline-grid; place-items: center; inline-size: 2rem; block-size: 2rem; border-radius: 50%; background: var(--accent-soft); color: var(--accent-ink); }
.rt-go .ci { --ci-size: 16px; }
.rt-actions { position: relative; z-index: 2; display: flex; gap: 2px; }
.icon-btn-danger { color: var(--bad); }

/* On a hover-capable screen the actions wait until the tile is reached, and the arrow says "open" by
   sliding in; on touch they stay visible, because there is no hover to reveal them. */
@media (hover: hover) {
  .rt-actions { opacity: 0; transform: translateY(8px); transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease-out); }
  .rt:hover .rt-actions, .rt:focus-within .rt-actions { opacity: 1; transform: none; }
  .rt-go { opacity: 0; transform: translateX(-10px); transition: opacity var(--dur) var(--ease), transform var(--dur-slow) var(--ease-spring); }
  .rt:hover .rt-go, .rt:focus-within .rt-go { opacity: 1; transform: none; }
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .rt:hover .rt-cover { background-position: 100% 50%; }
  .rt:hover .rt-cover::after { transform: translateX(130%); transition: transform .9s var(--ease-out); }
  .rt:hover .rt-art { transform: translateY(-6px) scale(1.09) rotate(-3deg); }
  .rt:hover .rt-kind { transform: translateY(-1px); }
}
.rt-kind { transition: transform var(--dur) var(--ease-out); }

/* The quick look. */
.ql-text { white-space: pre-wrap; line-height: 1.55; }
.ql-list { padding-inline-start: var(--s3); display: grid; gap: 4px; }
.ql-stack { display: grid; gap: var(--s1); }
.ql-item { padding: var(--s1); border-radius: var(--radius-field, 10px); background: var(--field); }
.ql-facts dd { min-inline-size: 0; overflow-wrap: anywhere; }
.drawer .dialog-foot { justify-content: space-between; flex-wrap: wrap; }

/* ---------- Dialogs wear the theme, not the danger colour ---------- */
/* The kit paints a dialog's picture red because its default dialog is a destructive confirm. Everything
   else — sharing a folder, naming an app, choosing a plan — is the theme's accent; only a dialog that
   says `data-tone="danger"` stays red. */
.dialog:not([data-tone="danger"]) .dialog-art { background: var(--accent-soft); color: var(--accent-ink); }

/* ---------- Plans ---------- */
.plan { display: grid; align-content: start; gap: var(--s1); }
.plan-price { font-size: var(--t3); font-weight: 700; color: var(--ink); }
.dialog-wide { inline-size: min(54rem, 94vw); max-inline-size: none; }
/* Plans fit as many columns as the dialog can give them, never a column too narrow to read a price in. */
.plans-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(13.5rem, 1fr)); gap: var(--gap); }
.plan-price { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 6px; white-space: nowrap; }
.plan .btn { white-space: normal; }
.plan { display: flex; flex-direction: column; }
.plan .btn { margin-block-start: auto; }
.plan-price { font-size: var(--t2); }

/* ---------- Password rules ---------- */
/* Each rule ticks itself as it is met. Unmet is plain, not red: it is a list to work through. */
.rules { list-style: none; display: grid; gap: 4px; margin-block: calc(-1 * var(--s0)) var(--s0); font-size: var(--t-1); color: var(--ink-3); }
.rules li { display: flex; align-items: center; gap: 8px; transition: color var(--dur) var(--ease); }
.rules li .ci { --ci-size: 14px; opacity: .35; transition: opacity var(--dur) var(--ease), transform var(--dur-slow) var(--ease-spring); }
.rules li[data-met] { color: var(--ok); }
.rules li[data-met] .ci { opacity: 1; transform: scale(1.15); }

.bento-badge { position: absolute; inset-inline-end: var(--s1); inset-block-start: var(--s1); z-index: 1; }

/* ---------- Phones ---------- */
/* Long words must never push a tile wider than the screen: the title's button is a shrinkable block, and
   every part of a tile may be narrower than its content. */
.rt-open { display: block; max-inline-size: 100%; text-align: start; overflow-wrap: anywhere; }
.rt-title, .rt-meta, .rt-excerpt, .rt-chips, .rt-body { min-inline-size: 0; }
.rt-title { overflow-wrap: anywhere; }
/* The kit's phone tab bar gives each tab a fifth of the width and lets a longer label spill into its
   neighbour ("Built-in apps" over "Workspaces"). Clip with an ellipsis instead; the full name is the tab's title. */
.tabbar .tab { min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* On a phone the edge handle sits on top of tile actions, and the built-in apps are already one tab away. */
@media (max-width: 860px) { .apps-drawer-handle { display: none; } }

/* ---------- Quick look: lists as a tag cloud, lists of things as numbered cards ---------- */
.ql-tags { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; }
.ql-tags li { padding: 3px 11px; border-radius: 999px; background: var(--field); color: var(--ink); font-size: var(--t-1); overflow-wrap: anywhere; }
.ql-cards { display: grid; gap: var(--s1); list-style: none; }
.ql-card { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s1); padding: var(--s1); border-radius: var(--radius-field, 12px); background: var(--field); }
.ql-index { display: inline-grid; place-items: center; inline-size: 1.7rem; block-size: 1.7rem; border-radius: 50%; background: var(--accent-soft); color: var(--accent-ink); font-size: var(--t-1); font-weight: 700; }
.ql-card-body { min-inline-size: 0; }
.ql-card .facts { gap: var(--s0); }
.ql-facts > div { min-inline-size: 0; }

/* A nested object is one column: its labels need room, and the drawer is narrow. A value that is itself an
   object or a list of things takes the whole row, under its own label. */
.ql-facts .ql-facts, .ql-card .ql-facts { grid-template-columns: minmax(0, 1fr); gap: var(--s0); }
.ql-facts > div:has(> dd > .ql-facts), .ql-facts > div:has(> dd > .ql-cards), .ql-facts > div:has(> dd > .ql-tags), .ql-facts > div:has(> dd > .ql-text) { grid-column: 1 / -1; }
.ql-facts .ql-facts > div { display: grid; grid-template-columns: minmax(6rem, 34%) minmax(0, 1fr); gap: var(--s1); align-items: baseline; }
.ql-facts .ql-facts dt { overflow-wrap: anywhere; }
/* The quick look is where a whole record is read: wider than the kit's default drawer, and inside a card
   inside a card the label sits above its value, so nothing is squeezed into a sliver. */
dialog.drawer { inline-size: min(38rem, 100vw); max-inline-size: 100vw; }
.ql-card .ql-facts > div, .ql-card .ql-card .ql-facts > div { grid-template-columns: minmax(0, 1fr); gap: 2px; }
.ql-card .ql-card { padding: var(--s0); }

/* ---------- Quick look: full screen, and the generated page ---------- */
.ql-data[hidden], .ql-page[hidden], .drawer .dialog-foot[hidden] { display: none; }
.ql-head-actions { display: flex; gap: 4px; flex: none; align-items: flex-start; }
/* The whole screen: the drawer loses its rounded edge and the reading column stays a readable width. */
dialog.drawer { transition: inline-size .22s ease; }
dialog.drawer.is-full { inline-size: 100vw; max-inline-size: 100vw; border-radius: 0; }
dialog.drawer.is-full .dialog-body > .ql-data { max-inline-size: 60rem; margin-inline: auto; }
@media (prefers-reduced-motion: reduce) { dialog.drawer { transition: none; } }

.pg-lead { margin-block-end: var(--s2); color: var(--ink-2); }
.pg-kinds { display: flex; flex-wrap: wrap; gap: 8px; margin-block-end: var(--s2); }
.pg-kind { padding: 8px 14px; border: 1px solid var(--rule); border-radius: 999px; background: var(--paper); color: var(--ink); font: inherit; font-size: var(--t-1); cursor: pointer; transition: background .15s, border-color .15s, transform .15s; }
.pg-kind:hover { border-color: var(--accent); transform: translateY(-1px); }
.pg-kind[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-ink); font-weight: 600; }
.pg-working { display: flex; gap: var(--s2); align-items: center; padding: var(--s3) 0; }
.pg-spinner { inline-size: 28px; block-size: 28px; border-radius: 50%; border: 3px solid var(--accent-soft); border-block-start-color: var(--accent); animation: pg-spin .9s linear infinite; flex: none; }
@keyframes pg-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .pg-spinner { animation-duration: 3s; } }
.pg-bar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-block-end: var(--s1); }
.pg-bar-gap { flex: 1; }
/* The frame is a white sheet: the page brings its own colours, whatever the panel's theme is. */
.pg-stage { block-size: calc(100dvh - 15rem); min-block-size: 22rem; border-radius: 14px; overflow: hidden; border: 1px solid var(--rule); background: Canvas; color-scheme: light; }
.pg-frame { display: block; inline-size: 100%; block-size: 100%; border: 0; background: Canvas; color-scheme: light; }
.pg-stage:fullscreen { block-size: 100vh; border: 0; border-radius: 0; }
.pg-note { margin-block-start: var(--s1); font-size: var(--t-1); }
