/* ModelHub's palette. The vendored daisyUI sheet is served before this file, and
   every rule daisyUI ships lives inside @layer while these do not — an unlayered
   declaration beats a layered one regardless of specificity. That is what lets
   the remap below win, and it is also the rule to respect when editing: never
   style a bare element that also carries a daisyUI component class, because that
   rule would quietly override the component. */
/* The scales below are the difference between "styled" and "designed": before
   them every value in this file was a literal, so nothing could be consistent
   on purpose. Three rules keep them honest — spacing comes only from the 4px
   ladder, surfaces carry a hairline instead of a shadow, and --accent is spent
   on actions and focus only, never decoration. */
:root{
  /* The light palette is the default; the dark one is the same design seen at
     night rather than a second design. Every colour a rule below uses is a role
     named here — a literal in a component rule is a theme waiting to break. */
  color-scheme:light;
  /* surfaces. --line draws component outlines; --hairline draws separators
     inside a surface, where a full-strength border would read as a box. */
  --bg:#f6f7f9;--panel:#ffffff;--panel2:#f1f3f6;
  --line:#dde2e9;--hairline:rgba(15,23,42,.08);--edge:rgba(15,23,42,.16);
  /* text, in the order a page uses it: the strongest for names and headings, the
     label level for form captions, then two levels of quiet. */
  --ink:#1f2937;--ink-strong:#0b1220;--ink-label:#334155;--nav-ink:#475569;
  --muted:#5b6b7f;--faint:#8b98a8;
  --accent-fill:#2563eb;--accent:#2563eb;--accent-ink:#1d4ed8;--on-accent:#fff;
  --success:#047857;--danger:#b91c1c;--warning:#b45309;
  --danger-line:#fecaca;
  /* the three message surfaces, which are tints in either theme */
  --notice-ink:#065f46;--notice-bg:#ecfdf5;--notice-line:#a7f3d0;
  --error-ink:#991b1b;--error-bg:#fef2f2;--error-line:#fecaca;
  --token-line:#a7f3d0;--token-bg:#ecfdf5;
  /* two interaction tints: a row under the pointer, and a control under it */
  --row-hover:rgba(15,23,42,.03);--hover-strong:rgba(15,23,42,.12);
  /* type ladder */
  --t-xs:11px;--t-sm:12px;--t-md:13px;--t-base:14px;--t-lg:16px;
  --t-xl:20px;--t-2xl:24px;--t-3xl:32px;
  /* 4px spacing ladder */
  --s-1:4px;--s-2:8px;--s-3:12px;--s-4:16px;--s-5:24px;--s-6:32px;--s-7:48px;
  /* two radii plus pills for status */
  --r-control:6px;--r-surface:8px;--r-pill:999px;
  /* overlays are the only things allowed to float */
  --e-overlay:0 12px 34px rgba(15,23,42,.16);
  --focus:2px solid var(--accent);
  --row-h:44px;
  --mono:ui-monospace,SFMono-Regular,Menlo,monospace;
  /* daisyUI's semantic colours remapped onto the roles above, so its components
     read as ModelHub instead of as stock daisyUI. These reference roles rather
     than values, so they follow whichever theme is on. */
  --color-base-100:var(--panel);--color-base-200:var(--panel2);--color-base-300:var(--line);
  --color-base-content:var(--ink);
  --color-primary:var(--accent-fill);--color-primary-content:var(--on-accent);
  --radius-box:var(--r-surface);--radius-field:var(--r-control);
  /* The tints a solid badge puts its label on are the one place a role cannot be
     reused across the themes: a pale mint needs dark text, a deep green needs
     white. */
  --color-success:var(--success);--color-success-content:#ecfdf5;
  --color-error:var(--danger);--color-error-content:#fef2f2;
  --color-warning:var(--warning);--color-warning-content:#fffbeb;
  --color-info:var(--accent);--color-info-content:#eff6ff;
  --color-neutral:#e2e8f0;--color-neutral-content:#0f172a;
}

/* The dark palette. It sits after the block above because both selectors match
   the same element at the same specificity, so the later one wins. */
[data-theme=dark]{
  color-scheme:dark;
  --bg:#0f1522;--panel:#1a2333;--panel2:#222d40;
  --line:#2f3b4f;--hairline:rgba(255,255,255,.07);--edge:rgba(255,255,255,.12);
  --ink:#e5e7eb;--ink-strong:#f9fafb;--ink-label:#cbd5e1;--nav-ink:#9fb0c7;
  --muted:#94a3b8;--faint:#64748b;
  --accent:#3b82f6;--accent-ink:#93c5fd;
  --success:#34d399;--danger:#f87171;--warning:#fbbf24;
  --danger-line:#7f1d1d;
  --notice-ink:#6ee7b7;--notice-bg:#064e3b59;--notice-line:#065f46;
  --error-ink:#fca5a5;--error-bg:#7f1d1d4d;--error-line:#991b1b;
  --token-line:#047857;--token-bg:#064e3b;
  --row-hover:rgba(255,255,255,.022);--hover-strong:rgba(255,255,255,.27);
  --e-overlay:0 12px 34px rgba(0,0,0,.55);
  --color-success-content:#04231a;--color-error-content:#2a0a0a;
  --color-warning-content:#2a1a02;--color-info-content:#0a1a2e;
  --color-neutral:#4b5563;--color-neutral-content:#e5e7eb;
}

*{box-sizing:border-box}
/* The vendored daisyUI has no sr-only helper, and the new list controls need
   one: a column caption that names the action column without printing a word
   over every row. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
body{margin:0;background:var(--bg);color:var(--ink);font:var(--t-base)/1.55 system-ui,sans-serif;-webkit-font-smoothing:antialiased}
h1{font-size:var(--t-3xl);line-height:1.15;margin:0 0 var(--s-2);letter-spacing:-.022em;font-weight:600}
h2{font-size:var(--t-xl);margin:0 0 var(--s-3);letter-spacing:-.011em;font-weight:600}
h3{font-size:var(--t-lg);margin:0 0 var(--s-3);font-weight:600}
/* Identifiers — model names, revisions, hashes, sizes — are read character by
   character, so they are monospaced with fixed-width digits. */
code{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:.94em}

/* One focus ring for the whole app. This is the cheapest signal that a page was
   built rather than assembled: the browser default is thin, inconsistent across
   controls, and nearly invisible on this background. Applied unlayered, so it
   also replaces daisyUI's own focus treatment on the components. */
a:focus-visible,button:focus-visible,summary:focus-visible,select:focus-visible,
textarea:focus-visible,input:focus-visible,[tabindex]:focus-visible,
input[type=checkbox]:focus-visible,input[type=file]:focus-visible{
  outline:var(--focus);outline-offset:2px}
/* Pointer users still get daisyUI's subtle state, but no ring. */
:focus:not(:focus-visible){outline:none}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}

header{background:var(--bg);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:20}
/* Scoped to the header on purpose: a bare nav{} rule also matches the
   repository tab strip and the pagination control, and its justify-content
   would stretch those across the full width. */
header nav,.container{width:min(1180px,calc(100% - 40px));margin:auto}
header nav{min-height:64px;display:flex;align-items:center;justify-content:space-between;gap:24px}
.nav-left,.nav-right,.nav-links,.user-menu{display:flex;align-items:center;gap:6px}
.brand{display:flex;align-items:center;gap:10px;color:var(--ink-strong);font-size:17px;font-weight:700;text-decoration:none;white-space:nowrap;margin-right:14px}
.brand-mark{display:grid;place-items:center;width:30px;height:30px;border-radius:9px;background:linear-gradient(140deg,#60a5fa,var(--accent));color:var(--on-accent);font-size:11px;font-weight:800}
.nav-links a,.user-menu a{display:flex;align-items:center;height:32px;padding:0 12px;border-radius:8px;color:var(--nav-ink);text-decoration:none;font-weight:500}
.nav-links a:hover,.user-menu a:hover{background:var(--panel2);color:var(--ink-strong)}
.user-chip{gap:8px!important;padding-left:6px!important;color:var(--ink-strong)!important}
/* The theme control. Its mark is a half-filled circle rather than a moon or a
   sun: it needs no icon font, it draws in the header's own ink in either theme,
   and it does not claim to show which theme is on — the accessible name says
   what pressing it does. */
.theme-toggle{width:32px;min-height:32px;padding:0}
.theme-glyph{display:block;width:13px;height:13px;border:1.6px solid currentColor;border-radius:50%;
  background:linear-gradient(to right,currentColor 0 50%,transparent 50% 100%)}

.avatar{display:block;width:28px;height:28px;border:1px solid var(--line);border-radius:50%;background:var(--panel2);object-fit:cover}
.avatar-large{width:64px;height:64px}
.avatar-form{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin:0 0 12px}
.avatar-form label{display:flex;align-items:center;gap:10px}
.avatar-form input[type=file]{padding:8px}

.container{padding:32px 0 64px}
.muted{color:var(--muted)}
.eyebrow{color:var(--accent-ink);text-transform:uppercase;letter-spacing:.08em;font-size:11px;font-weight:700;margin:0}
.subhead{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;margin-bottom:24px}
.subhead-actions{display:flex;align-items:center;gap:10px}
.panel-head{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;margin-bottom:20px}
.panel-actions{display:flex;align-items:flex-end;gap:12px;flex-wrap:wrap}

/* daisyUI's card sets the surface and radius; card-body sets the padding. The
   two travel together in the templates, and this trims card-body's default
   padding to the app's denser rhythm. */
/* daisyUI's card sets the radius and the flex column but no surface of its own,
   so the background and border are ours. */
.card{background:var(--panel);border:1px solid var(--line)}
.card-body{padding:22px}
.repo-panel{margin-top:18px}
.card.danger-zone{border-color:var(--danger-line)}
.table-wrap{overflow-x:auto;border:1px solid var(--line);border-radius:var(--r-surface);background:var(--panel)}
/* A namespace/name pair and a timestamp are single tokens. Letting them break
   mid-word is what made the listings look broken; a table too wide for its
   container scrolls instead. The nowrap cells already give every table its
   content width, so no min-width is needed here — forcing one would put a
   scrollbar under short tables that fit comfortably. */
.table-wrap .table :where(th,td){padding:11px 14px;white-space:nowrap}
/* Column captions take --muted, not --faint: at 11px the faint level measures
   3.3:1 on --panel, which is below the 4.5:1 small-text threshold, and these
   captions are the only label a column of numbers ever gets. */
.table-wrap .table thead th{font-size:var(--t-xs);letter-spacing:.06em;text-transform:uppercase;color:var(--muted);font-weight:600;white-space:nowrap}
/* Separators inside a surface are hairlines, not borders: a full-strength line
   under every row turns a list into a grid and costs the eye more than the rows
   are worth. Hover is the only row state — no zebra striping. */
.table-wrap .table tbody td{border-bottom-color:var(--hairline);vertical-align:middle}
.table-wrap .table tbody tr:last-child td{border-bottom:0}
.table-wrap .table tbody tr:hover{background:var(--row-hover)}
/* Metrics line up by digit, so a column of sizes can be scanned without
   reading it. Templates tag these cells with .num. */
.table-wrap .table .num{text-align:right;font-variant-numeric:tabular-nums}
/* A namespace and a name are one address. The namespace keeps its own link —
   jumping to everything under it is a real move — but reads as a qualifier
   rather than as a second, competing target. */
.repo-cell{display:inline-flex;align-items:baseline;gap:2px}
.repo-ns{color:var(--muted);text-decoration:none;font-weight:500}
.repo-ns:hover{color:var(--accent-ink)}
.repo-sep{color:var(--faint)}
.repo-link,.file-link{color:var(--ink-strong);text-decoration:none;font-weight:600}
.repo-link:hover,.file-link:hover{color:var(--accent-ink)}

.tabs{margin:0 0 22px}
/* daisyUI marks the selected tab with a short bar and gives the strip no line,
   so a repository's tab row sat at the same left edge, size and weight as the
   meta strip above it and read as a third row of measurements. It owns a
   baseline now, at full --line weight, because it outlines the page the way the
   header's rule does; the tabs are lifted onto it so the marker covers the line
   where it lands. The settings strip keeps the plain treatment, since its tabs
   jump to sections under a heading with no row above to be confused with.
   Padding stays daisyUI's either way: the marker's offset is driven by --tab-p,
   which daisyUI sets on .tabs, so overriding it here would desynchronise them. */
.repo-tabs{margin-top:var(--s-6);border-bottom:1px solid var(--line)}
.repo-tabs>.tab{margin-bottom:-1px}
.breadcrumbs{margin:0 0 18px;color:var(--muted)}
.breadcrumbs a{color:var(--accent-ink);text-decoration:none}
.breadcrumbs a:hover{text-decoration:underline}

.detail-header{margin-bottom:var(--s-5)}
/* The meta strip answers "what is this and how big is it" at a glance, so the
   values carry the weight and the labels stay quiet. The hairline above it
   separates the repository's identity from its measurements. */
.detail-meta{display:flex;flex-wrap:wrap;gap:var(--s-4) var(--s-6);margin-top:var(--s-5);padding-top:var(--s-4);border-top:1px solid var(--hairline);font-size:var(--t-xs);letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.detail-meta>div{min-width:0}
.detail-meta strong{display:block;margin-top:var(--s-1);color:var(--ink);font-size:var(--t-base);font-weight:600;letter-spacing:-.006em;text-transform:none;font-variant-numeric:tabular-nums}
.repo-title{display:flex;align-items:center;gap:16px}
.repo-title h1{margin:0;font-size:20px;min-width:0;overflow-wrap:anywhere}
.repo-icon{display:grid;place-items:center;width:44px;height:44px;border-radius:var(--r-surface);background:var(--panel2);border:1px solid var(--line);color:var(--accent-ink);font-weight:700;font-size:var(--t-lg);flex:none}
/* The badge belongs beside the name it qualifies; the action is what goes to the
   far edge. Stock daisyUI has no opinion here, so the earlier rule pushed the
   badge out and left the control stranded after it. */
.repo-actions{margin-left:auto;flex:none}

.pagination{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:18px}
.pagination .muted{margin-left:auto}
.pagination .join .btn{font-weight:600}

.row-form{display:grid;grid-template-columns:1fr 1fr auto auto;gap:12px;align-items:end}
/* A form whose item count does not fill the four tracks drops its submit button
   onto a 1fr track, where the default stretch turns it into a full-width bar. */
.row-form>.btn{justify-self:start}
.deployment-form{grid-template-columns:minmax(0,2fr) minmax(0,1fr) auto}
.deployment-form>label{min-width:0}
.deployment-form .select{min-width:0;max-width:100%;text-overflow:ellipsis}
.deployment-task{overflow-wrap:anywhere}
.deployment-task .progress{max-width:100%}
/* Not .stack: daisyUI owns that name for its stacked-cards component, which
   puts every child in a single grid area and would collapse the form. */
form.form-stack{display:grid;gap:16px;max-width:520px}
/* Every other submit in the app is sized to its label; a stacked form would
   otherwise stretch its button across the full column. */
form.form-stack>.btn{justify-self:start}
label{display:grid;gap:7px;font-weight:600;color:var(--ink-label)}
/* daisyUI sizes an input to clamp(3rem,20rem,100%), which stops short of the
   field it sits in; inside a label it should fill that field. */
label>.input,label>.select{width:100%}
.check{display:flex!important;align-items:center;gap:9px;font-weight:500}
.check input{flex:none}
.table-gap{margin-top:20px}
.section-gap{margin-top:26px}
.row-actions{display:flex;align-items:center;gap:6px}
.login-foot{margin-top:18px;text-align:center}
.notice,.error{display:flex;gap:8px;margin:0 0 18px;padding:11px 14px;border-radius:var(--radius-field);font-weight:500}
.notice{color:var(--notice-ink);background:var(--notice-bg);border:1px solid var(--notice-line)}
.error{color:var(--error-ink);background:var(--error-bg);border:1px solid var(--error-line)}
.token{padding:14px;border:1px solid var(--token-line);background:var(--token-bg);border-radius:var(--radius-field);overflow-wrap:anywhere}

.auth-shell{min-height:100vh;display:grid;place-items:center;padding:32px 16px}
.login{width:min(440px,100%);background:var(--panel);border:1px solid var(--line);padding:32px;border-radius:var(--radius-box)}
.login-header{text-align:center;margin-bottom:26px}
.login-header .brand-mark{margin:0 auto 14px;width:48px;height:48px;border-radius:14px;font-size:15px}
.login-header h1{font-size:24px}
.login form{display:grid;gap:16px}
.login .alternate{margin-top:26px;padding-top:22px;border-top:1px solid var(--line)}
.login .alternate summary{cursor:pointer;color:var(--accent-ink);text-align:center}
.login .alternate form{margin-top:18px}

/* Authentication pages share the house palette, but not daisyUI's accent
   button styles. Explicitly scoped controls keep all three entry points aligned. */
.mh-auth{min-height:100svh;display:grid;place-items:center;padding:40px 20px}
.mh-auth-frame{width:min(480px,100%);min-width:0}
.mh-auth-brand{display:flex;align-items:center;justify-content:center;gap:12px;width:fit-content;margin:0 auto 28px;color:var(--ink-strong);text-decoration:none;font-size:20px;font-weight:700;letter-spacing:-.5px}
.mh-auth-mark{display:grid;place-items:center;width:40px;height:40px;border-radius:10px;background:var(--accent);color:var(--on-accent);font-size:13px;font-weight:750;letter-spacing:0}
.mh-auth-card{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:36px}
.mh-auth-heading{margin-bottom:28px}
.mh-auth-eyebrow{font-size:10px;font-weight:700;letter-spacing:.16em;color:var(--accent-ink);margin:0 0 12px}
.mh-auth-heading h1{font-size:30px;line-height:1.16;font-weight:650;letter-spacing:-1px;margin:0 0 12px;color:var(--ink-strong)}
.mh-auth-description{font-size:14px;line-height:1.6;color:var(--muted);margin:0;max-width:360px}
.mh-auth-form{display:grid;gap:18px;margin:0}
.mh-auth-field{display:grid;gap:7px;font-size:13px;font-weight:550;color:var(--ink-label)}
.mh-auth-field input{display:block;width:100%;min-width:0;min-height:46px;border:1px solid var(--edge);border-radius:6px;background:var(--panel);padding:11px 13px;color:var(--ink-strong);font:400 14px/1.5 system-ui,sans-serif;transition:border-color .15s}
.mh-auth-field input:hover{border-color:var(--muted)}
.mh-auth-field input:focus{border-color:var(--accent)}
.mh-auth-field input::placeholder{color:var(--muted);font-weight:400}
.mh-auth-button{display:flex;justify-content:center;align-items:center;gap:12px;min-height:46px;width:100%;border:1px solid transparent;border-radius:6px;padding:12px 14px;font:600 14px/1.45 system-ui,sans-serif;text-decoration:none;cursor:pointer;white-space:normal;text-align:center;transition:background .15s,border-color .15s}
.mh-auth-button>span:last-child:not(:first-child){margin-left:auto}
.mh-auth-primary{background:var(--accent-fill);color:var(--on-accent)}
.mh-auth-primary:hover{background:var(--accent-fill);color:var(--on-accent);filter:brightness(.92)}
.mh-auth-secondary,.mh-auth-research{background:var(--panel);border-color:var(--edge);color:var(--ink-strong)}
.mh-auth-secondary:hover,.mh-auth-research:hover{background:var(--panel2);border-color:var(--muted)}
.mh-auth-research{justify-content:flex-start}
.mh-auth-research-icon{display:grid;place-items:center;background:var(--ink-strong);color:var(--panel);border-radius:5px;width:26px;height:26px;font:700 13px/1 system-ui,sans-serif;flex:none}
.mh-auth-divider{display:flex;align-items:center;gap:14px;margin:26px 0;color:var(--muted);font-size:9px;font-weight:600;letter-spacing:.1em;text-align:center}
.mh-auth-divider::before,.mh-auth-divider::after{content:"";height:1px;background:var(--line);flex:1}
.mh-auth-foot{margin:26px 0 0;padding-top:22px;border-top:1px solid var(--line);text-align:center;color:var(--muted);font-size:13px}
.mh-auth-foot a{color:var(--accent-ink);font-weight:600;text-decoration:none;text-underline-offset:3px}
.mh-auth-foot a:hover{text-decoration:underline}
.mh-auth-bottom{margin:22px 0 0;text-align:center;color:var(--muted);font-size:11px}
.mh-auth-help{margin:-9px 0 0;color:var(--muted);font-size:12px;line-height:1.55}
.mh-auth-policy{margin:22px 0 0}
.mh-auth-error{margin:0 0 22px;padding:12px 14px;background:var(--error-bg);color:var(--error-ink);border:1px solid var(--error-line);border-radius:6px;font-size:13px;overflow-wrap:anywhere}
.mh-auth-identity{display:flex;align-items:center;gap:12px;padding:16px;background:var(--panel2);border:1px solid var(--line);border-radius:8px;margin-bottom:26px;overflow-wrap:anywhere}
.mh-auth-identity>div{min-width:0;flex:1}
.mh-auth-check{display:grid;place-items:center;width:30px;height:30px;border-radius:50%;background:var(--notice-bg);color:var(--success);font-weight:700;flex:none}
.mh-auth-caption{display:block;font-size:11px;color:var(--muted);margin-bottom:2px}
.mh-auth-identity strong{font-size:14px;color:var(--ink-strong)}
.mh-auth-handle{display:block;font-size:12px;color:var(--muted)}
.mh-auth-verified{font-size:10px;color:var(--success);font-weight:600;flex:none}
.mh-auth-section-heading{margin:0 0 20px}
.mh-auth-section-heading h2,.mh-auth-create-body h2{font-size:16px;color:var(--ink-strong);margin:0 0 6px;font-weight:600}
.mh-auth-section-heading p,.mh-auth-create-body>p{color:var(--muted);font-size:12px;line-height:1.6;margin:0}
.mh-auth-create{border:1px solid var(--line);border-radius:8px}
.mh-auth-create summary{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:52px;padding:14px 16px;cursor:pointer;font-size:13px;font-weight:600;color:var(--ink-strong);list-style:none}
.mh-auth-create summary::-webkit-details-marker{display:none}
.mh-auth-create summary>span{color:var(--accent-ink);font-size:20px;flex:none}
.mh-auth-create[open] summary>span{transform:rotate(45deg)}
.mh-auth-create-body{border-top:1px solid var(--line);padding:20px 16px}
.mh-auth-create-body .mh-auth-form{margin-top:20px}
@media(max-width:540px){.mh-auth{padding:24px 16px;align-items:start}.mh-auth-card{padding:26px 22px}.mh-auth-heading h1{font-size:26px}.mh-auth-brand{margin-bottom:22px}.mh-auth-verified{display:none}.mh-auth-divider{letter-spacing:.04em;font-size:9px}}

.profile-grid{display:grid;gap:4px}
.profile-row{display:flex;align-items:center;justify-content:space-between;gap:20px;padding:13px 0;border-bottom:1px solid var(--line)}
.profile-row:last-child{border-bottom:0}
.card-layout{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:22px;align-items:start}
.card-tags{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-2);margin-bottom:var(--s-5)}
/* Card badges carry four different kinds of fact — what the licence allows, what
   runs it, what it is for, and free-form labels — and stock daisyUI draws all of
   them identically. Weighting them means the eye can skip the ones it does not
   need instead of reading six equal pills. */
.card-tags .tag-license{border-color:color-mix(in oklab,var(--success) 45%,transparent);color:var(--success);background:transparent}
.card-tags .tag-pipeline{background:color-mix(in oklab,var(--accent) 22%,transparent);border-color:transparent;color:var(--accent-ink)}
.card-tags .tag-library{border-color:var(--edge);color:var(--muted);background:transparent}
.card-tags .tag-free{border-color:transparent;background:var(--panel2);color:var(--muted)}

/* Files are read for one question first: is this the weights, or something I can
   actually open? A category mark answers it before the name is read. */
.file-cell{display:inline-flex;align-items:center;gap:9px}
.file-kind{display:inline-block;width:8px;height:8px;border-radius:2px;flex:none;background:var(--faint)}
.file-kind.k-weights{background:var(--accent)}
.file-kind.k-config{background:var(--warning)}
.file-kind.k-data{background:var(--success)}
.file-kind.k-doc{background:var(--muted)}
.file-kind.k-code{background:var(--accent-ink)}
/* A folder is not a category of file, so it takes the shape that says there is
   more inside rather than one of the category colours. The tab is the mark's own
   background, so the two cannot drift apart. */
.folder-mark{position:relative;display:inline-block;width:11px;height:9px;border-radius:0 2px 2px 2px;background:var(--muted);flex:none}
.folder-mark::before{content:"";position:absolute;left:0;top:-3px;width:5px;height:3px;border-radius:2px 2px 0 0;background:inherit}
/* The folder path is a sub-navigation inside the panel, not the page breadcrumb
   above the title, so it is set a size quieter — it is only ever read to answer
   "where am I" or to go back up. */
.path-bar{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:0 0 var(--s-4);font-size:var(--t-xs)}
.path-bar a{color:var(--muted);text-decoration:none;font-weight:600}
.path-bar a:hover{color:var(--accent-ink)}
.path-bar .path-here{color:var(--ink);font-weight:600}
.path-sep{color:var(--faint)}
/* A truncated digest is still the full digest: the title carries all of it. */
.hash{color:var(--muted);cursor:help}
.viewer-files{display:grid;gap:10px}

.markdown{line-height:1.7;overflow-wrap:anywhere}
.markdown img{max-width:100%;height:auto}
.markdown h1,.markdown h2,.markdown h3{border-bottom:1px solid var(--line);padding-bottom:8px}
.markdown pre{background:var(--bg);padding:14px;border-radius:var(--radius-field);overflow-x:auto}
.markdown code{background:var(--panel2);padding:2px 5px;border-radius:4px}
.markdown pre code{background:none;padding:0}
.markdown table{border-collapse:collapse;width:100%;margin:16px 0}
.markdown th,.markdown td{border:1px solid var(--line);padding:8px 10px;text-align:left}
.markdown blockquote{border-left:3px solid var(--line);margin:16px 0;padding:4px 16px;color:var(--muted)}

.model-tree h3{font-size:14px;margin:16px 0 6px}
.model-tree ul{list-style:none;margin:0;padding:0}
.model-tree li{padding:4px 0}
.tree-base{display:flex;justify-content:space-between;gap:12px;align-items:baseline;padding:10px 0;border-bottom:1px solid var(--line)}
.tree-base>span{flex:none;white-space:nowrap}
.tree-base>a,.tree-base>strong{min-width:0;overflow-wrap:anywhere}
.tree-derived h3{color:var(--muted)}

.token-copy{display:inline-grid;vertical-align:middle;margin-left:12px}
/* The copy affordance belongs to the whole block, not to whatever the last line
   of the command happens to be, so it is pinned to the corner instead of flowing
   after the text and drifting with every wrap. */
.cli-command{position:relative}
.cli-command .cli-copy{position:absolute;top:8px;right:8px}
.cli-copy,.token-copy{place-items:center;width:26px;height:26px;min-height:26px;padding:0;border:1px solid var(--line);background:transparent;color:var(--muted)}
.cli-copy:hover,.token-copy:hover{background:var(--panel2);color:var(--ink-strong)}
.cli-copy:focus-visible,.token-copy:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.cli-copy.copied{color:var(--success);border-color:var(--success)}
.cli-copy.copy-failed{color:var(--danger);border-color:var(--danger)}
.copy-icon{position:relative;display:block;width:11px;height:11px;border:1.25px solid currentColor;border-radius:2px}
/* Two overlapping squares drawn with borders only. The back square keeps just
   its top and left edges, so the glyph needs no fill colour and therefore reads
   correctly on the code block and on the green token panel alike. */
.copy-icon::before{content:"";position:absolute;left:-4px;top:-4px;width:9px;height:9px;border:1.25px solid currentColor;border-right-color:transparent;border-bottom-color:transparent;border-radius:2px 0 0 0}

/* A healthy sync is the expected state of nearly every row, so it gets a dot and
   no words. Only a state someone has to act on earns text, and only that state
   earns the width. */
.sync-retry{display:inline-grid;place-items:center;width:20px;height:20px;min-height:20px;padding:0;border:0;background:transparent;color:inherit;cursor:pointer}
.sync-retry:hover{color:var(--ink-strong)}
.sync-retry:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.retry-icon{position:relative;display:block;width:12px;height:12px;border:1.5px solid currentColor;border-radius:50%;border-top-color:transparent;transform:rotate(-40deg)}
.retry-icon::after{content:"";position:absolute;top:-3px;right:-2px;border:3px solid transparent;border-bottom-color:currentColor;transform:rotate(80deg)}

.scope-field{display:grid;gap:7px;font-weight:600;color:var(--ink-label);min-width:190px}
.scope-picker{position:relative}
.scope-picker summary{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:40px;padding:0 12px;border:1px solid var(--line);border-radius:var(--radius-field);background:var(--panel2);cursor:pointer;font-weight:400;color:var(--ink);list-style:none}
.scope-picker summary::-webkit-details-marker{display:none}
.scope-picker summary::after{content:"\25BE";color:var(--muted);flex:none}
.scope-picker[open] summary{border-color:var(--accent)}
.scope-chips{display:flex;flex-wrap:nowrap;gap:4px;overflow:hidden;min-width:0}
.scope-chips .chip{display:inline-flex;align-items:center;gap:5px;padding:2px 5px 2px 8px;border-radius:10px;background:var(--accent-fill);color:var(--on-accent);font-size:11px;font-weight:500;white-space:nowrap;pointer-events:none}
.scope-chips .chip.more{padding:2px 8px;background:var(--panel);color:var(--muted)}
.scope-chips .chip-x{pointer-events:auto;cursor:pointer;padding:0 3px;border-radius:50%;font-weight:700;line-height:1}
.scope-chips .chip-x:hover{background:var(--hover-strong)}
.scope-menu{position:absolute;right:0;top:46px;z-index:10;width:min(330px,calc(100vw - 64px));max-height:330px;overflow:auto;padding:12px;background:var(--panel2);border:1px solid var(--line);border-radius:var(--radius-box);box-shadow:var(--e-overlay)}
.scope-menu .check{min-height:auto;padding:5px 0;font-weight:400;font-size:13px}
.scope-menu .check span.muted{font-size:11px;flex:none;white-space:nowrap}
.scope-menu .scope-group{margin:12px 0 2px;font-size:11px;letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
.scope-menu .scope-group:first-child{margin-top:0}
.scope-menu .scope-hint{margin:0 0 6px;font-size:12px;color:var(--muted)}
.scope-list-static{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,300px),1fr));gap:4px 18px;margin-bottom:14px}
.scope-list-static .check{min-height:auto;padding:4px 0;font-weight:400;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.scope-list-static .scope-hint,.scope-list-static .scope-group{grid-column:1/-1}
.scope-actions{display:flex;align-items:center;gap:12px}

.dialog-card pre,.cli-guide pre{margin:0 0 16px;padding:14px;overflow:auto;background:var(--bg);border:1px solid var(--line);border-radius:var(--radius-field);white-space:pre-wrap;overflow-wrap:anywhere}
/* Reserve the corner the copy button is pinned to, so a long command cannot run
   underneath it. Two classes deep to outrank the .dialog-card pre padding. */
.dialog-card .cli-command{padding-right:52px}
/* daisyUI makes .modal-box itself the scroll container, so a trailing
   .modal-action scrolls out of reach on a dialog taller than the screen. Pin it
   to the bottom of the scrollport. A sticky child can never leave its parent's
   content box, so the box's own bottom padding would hold the bar that far off
   the bottom edge; drop that padding and let the bar carry the space instead.
   The negative side margins cancel the horizontal padding so the bar spans the
   full width. The height cap is the one daisyUI's own modal variants use: the
   base rule allows a full viewport, which reads as a page rather than a dialog. */
/* A closed native <dialog> is display:none in the user agent sheet, but the
   vendored sheet styles .modal with display:grid, and an author rule beats the
   user agent whatever the specificity — so the dialog stayed in the layout,
   fixed at 100% of the viewport with nothing in it, and every page that owns one
   ended in more than a screen of empty space. Closing the box is this app's job
   because it is this app that asked for the class. */
dialog.modal:not([open]){display:none}
.modal-box{max-height:calc(100vh - 5em)}
.modal-box:has(>.modal-action){padding-bottom:0}
.modal-box>.modal-action{position:sticky;bottom:0;margin:20px -24px 0;padding:14px 24px 20px;background:var(--panel);border-top:1px solid var(--hairline)}
/* Clicking outside a native <dialog> closes nothing on its own. daisyUI's
   pattern is a sibling form that submits method="dialog", but its own
   .modal-backdrop never receives a click. Two reasons, both fixed here: it is a
   grid item placed at row 1 / column 1, and because .modal-box is capped at
   32rem that grid area shrinks to the box, leaving the backdrop exactly behind
   it; and it is itself a grid whose auto-sized area collapses the injected
   button to its own text. An absolutely positioned grid child with a definite
   grid position is contained by its grid area, so the placement has to be
   cleared as well for inset:0 to mean the whole dialog, and a block box lets the
   button's 100% resolve against the dialog instead of against its own text. The
   button must not inherit the base button styling either. */
.modal-backdrop{position:absolute;inset:0;grid-row:auto;grid-column:auto;display:block}
.modal-backdrop button{display:block;width:100%;height:100%;padding:0;border:0;background:transparent;cursor:default}
.cli-guide{margin-top:20px}
.cli-guide ol{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;margin:0;padding:0;list-style:none}
.cli-guide li{min-width:0}
.cli-guide li strong{display:block;margin-bottom:8px}
.cli-guide .muted{margin:0}

/* ============ the repository list ============
   A row answers what someone scanning a hub is asking, in the two lines the eye
   takes in at once: where it lives and what it is called, then the few facts
   that decide whether to open it. Nothing else earns a place here. The licence,
   the tags, the provenance and the replication state are read on the page a
   reader opens, where each is the subject rather than one line among thirty.

   The name is one line and never wraps. Repository names here are generated and
   run to sixty characters; letting them wrap made one row four lines tall beside
   a neighbour's one, and since a grid stretches every row to the tallest, the
   difference showed up as blank space inside the short ones. The full name is in
   the link's title, and the link is the row's own target. */
.list-bar{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--s-3);margin-bottom:var(--s-4)}
.list-field{display:grid;gap:7px;font-weight:600;color:var(--ink-label);font-size:var(--t-sm)}
.list-search{flex:1 1 240px;min-width:200px}
.list-empty{margin:0;padding:var(--s-6);border:1px dashed var(--line);border-radius:var(--r-surface);color:var(--muted);text-align:center}

.repo-rows{display:grid;grid-template-columns:repeat(auto-fill,minmax(430px,1fr));gap:2px var(--s-4);margin:0;padding:0;list-style:none}
.repo-row{display:flex;align-items:center;gap:var(--s-3);padding:9px 11px;border-radius:var(--r-control);min-width:0}
.repo-row:hover{background:var(--panel)}
.repo-row .repo-icon{width:28px;height:28px;border-radius:7px;font-size:var(--t-xs)}
.repo-row-text{display:grid;gap:3px;min-width:0}
.repo-row .repo-cell{display:flex;align-items:baseline;min-width:0;font-size:var(--t-base)}
.repo-row .repo-ns,.repo-row .repo-sep{flex:none}
.repo-row .repo-link{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--accent-ink)}
.repo-row .repo-link:hover{text-decoration:underline}
/* Facts wrap independently of the repository identifier at narrow widths. */
.repo-facts{display:flex;align-items:center;min-width:0;overflow:hidden;margin:0;color:var(--muted);font-size:var(--t-sm)}
.repo-facts>span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.repo-facts>span+span::before{content:"·";color:var(--faint);margin:0 6px}
.repo-private{color:var(--warning)}

/* The upload channel is provenance and only the repository page shows it, so it
   is styled where it is used: beside the name it qualifies. */
.channel{display:inline-flex;align-items:center;padding:2px 8px;border:1px solid var(--line);border-radius:var(--r-pill);
  color:var(--muted);font-size:var(--t-xs);font-weight:600;white-space:nowrap}
.repo-title .channel{flex:none}

/* A list heading carries the size of the collection, which is a number of
   repositories and not a measure of anything. */
.count{color:var(--muted);font-size:var(--t-lg);font-weight:500;font-variant-numeric:tabular-nums;margin-left:var(--s-2)}

/* ============ replication status ============
   The copy a revision is being given, shown beside the channel chip that says
   where the original came in. It is always shown rather than only when it goes
   wrong: whether the second copy exists is what a reader came to the page to
   find out, and a page that said nothing about it left "replicated" and "never
   started" looking the same. Colour carries the state, the words name it, and
   only a failed copy carries an action. */
.replica{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border:1px solid var(--line);border-radius:var(--r-pill);
  font-size:var(--t-xs);font-weight:600;white-space:nowrap;flex:none}
.replica-dot{width:6px;height:6px;border-radius:50%;background:currentColor;flex:none}
.replica-store{font-family:var(--mono);letter-spacing:.02em}
.replica-ok{color:var(--success);border-color:color-mix(in oklab,var(--success) 45%,transparent)}
.replica-failed{color:var(--danger);border-color:color-mix(in oklab,var(--danger) 45%,transparent)}
.replica-running{color:var(--accent-ink);border-color:color-mix(in oklab,var(--accent) 45%,transparent)}
.replica-waiting{color:var(--warning);border-color:color-mix(in oklab,var(--warning) 40%,transparent)}
/* An in-flight replication is the one state expected to change on its own, so
   its dot breathes. The reduced-motion rule at the top of the file already
   flattens this for anyone who asked for that. */
.replica-running .replica-dot{animation:pulse 1.4s ease-in-out infinite}
@keyframes pulse{50%{opacity:.35}}

/* ============ repository specification ============
   The model card is prose, so the facts a reader scans before reading it —
   licence, pipeline, base model, replication — sit beside it in a definition
   list rather than inside the paragraph flow. */
.repo-side{display:grid;gap:var(--s-5);align-content:start}
.spec{display:grid;gap:0;margin:0}
.spec-row{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s-3);padding:9px 0;border-bottom:1px solid var(--hairline);font-weight:400}
.spec-row:last-child{border-bottom:0}
.spec-row dt{color:var(--muted);font-size:var(--t-md)}
.spec-row dd{margin:0;text-align:right;font-weight:600;font-size:var(--t-md);overflow-wrap:anywhere}
.spec-base{display:block;font-family:var(--mono);font-size:var(--t-sm)}

/* ============ the file listing ============
   Files are read for two questions: is this the weights or something I can
   open, and how much of the revision is it? The category mark answers the
   first before the name is read, the bar answers the second at a glance, and
   the digest rides on the link instead of holding a column of its own. */
.files-table .size-cell{display:inline-flex;align-items:center;justify-content:flex-end;gap:10px}
.size-num{min-width:62px;display:inline-block;text-align:right;font-variant-numeric:tabular-nums}
.size-track{width:64px;height:4px;border-radius:2px;background:var(--panel2);flex:none;overflow:hidden}
.size-fill{display:block;height:100%;background:color-mix(in oklab,var(--accent) 70%,transparent)}
.row-actions{display:flex;align-items:center;justify-content:flex-end;gap:var(--s-1)}
.row-actions .btn{color:var(--muted)}
.row-actions .btn:hover{color:var(--ink)}
.files-note{margin:var(--s-4) 0 0;font-size:var(--t-sm)}

@media(max-width:1000px){
  .card-layout{grid-template-columns:1fr}
  /* Three columns of CLI steps are unreadable well before this width; two is the
     step down, not one. */
  .cli-guide ol{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:760px){
  header nav,.container{width:calc(100% - 28px)}
  /* The brand, three section links, the account chip and the logout button do not
     fit one 353px row, and a flex row that cannot fit overflows the page rather
     than the element: the whole document scrolled sideways. Wrapping the nav
     keeps every control inside the viewport. */
  header nav{flex-wrap:wrap;min-height:auto;padding:var(--s-2) 0;row-gap:var(--s-2)}
  .nav-left,.nav-links{flex-wrap:wrap;min-width:0}
  .brand{margin-right:6px}
  .breadcrumbs{flex-wrap:wrap}
  .container{padding-top:var(--s-5)}
  .nav-links{gap:2px}
  .nav-right{gap:2px}
  .user-chip span{display:none}
  .row-form{grid-template-columns:1fr}
  .detail-meta{gap:var(--s-3) var(--s-5)}
  h1{font-size:var(--t-2xl)}
  /* A title and its action stack rather than squeezing the action to a sliver. */
  .subhead,.panel-head{align-items:flex-start;flex-direction:column;gap:var(--s-3)}
  .card-body{padding:18px}
  .table-wrap .table :where(th,td){padding:10px 12px}
  .cli-guide ol{grid-template-columns:1fr}
  /* One row per line is the point of the grid below this width, and the control
     strip stacks so the search box is not squeezed to an ellipsis. */
  .repo-rows{grid-template-columns:1fr}
  .list-bar .list-field,.list-bar .list-search{width:100%;flex:1 1 auto}
  /* The title keeps a readable width and the CLI button drops to its own row,
     rather than the action holding its width while the name is crushed to one
     character per line. */
  .repo-title{flex-wrap:wrap}
  .repo-title h1{flex:1 1 200px;overflow-wrap:break-word}
  .repo-actions{margin-left:0;flex:1 1 100%}
  .repo-actions .btn{width:100%}
  /* A file listing is read for its names and its sizes. The action column only
     repeats the download the name already is, so it is the one that goes; the
     name wraps instead of forcing the table to scroll sideways. */
  /* The size column is what this listing exists to answer, so it keeps a fixed
     width while the name column takes what is left and breaks its long tokens —
     a shard name has no spaces, and without a break rule it pushes the size off
     the edge of the screen. */
  .files-table{table-layout:fixed}
  .files-table .col-size{width:118px}
  .files-table td:first-child{overflow-wrap:anywhere}
  /* The name is wrapped in an inline-flex cell mark, so the break rule has to sit
     on that box as well: a flex container does not wrap its own text, and an
     unbreakable token inside it overflows the column instead. */
  .files-table .file-cell{min-width:0;overflow-wrap:anywhere}
  .files-table .size-track{width:44px}
  .files-table :where(th,td){white-space:normal}
  .files-table .row-actions{display:none}}

/* Shared navigation, dense data and form refinements. */
.skip-link{position:fixed;top:8px;left:16px;z-index:1000;transform:translateY(-150%);padding:10px 16px;background:var(--panel);color:var(--accent-ink);border:1px solid var(--accent);border-radius:var(--r-control)}
.skip-link:focus{transform:none}
.nav-links a[aria-current],.user-chip[aria-current]{background:var(--panel2);color:var(--accent-ink);font-weight:650}
#main-content:focus{outline:none}
:where(#profile,#security,#api-tokens,#edit-scope){scroll-margin-top:100px}
.field-help{display:block;color:var(--muted);font-size:var(--t-sm);font-weight:400;line-height:1.6}
.profile-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;max-width:520px}
.profile-row{display:grid;grid-template-columns:100px minmax(0,1fr);gap:12px;padding:10px 0;border:0;align-items:baseline;justify-content:normal;overflow-wrap:anywhere}
.scope-editor{border-top:1px solid var(--line);padding-top:24px}
.scope-menu .check{overflow-wrap:anywhere;white-space:normal}
.scope-chips .chip-x{display:inline-grid;place-items:center;min-width:24px;min-height:24px;padding:0;border:0;background:transparent;color:inherit;font:inherit;cursor:pointer}
.table-scroll-hint{font-size:var(--t-sm);margin:12px 0 8px}
.tokens-table td:nth-child(3){white-space:normal;overflow-wrap:anywhere;min-width:160px;max-width:320px}
.repo-row:focus-within{background:var(--panel)}
.repo-row .repo-link:focus-visible{white-space:normal;overflow:visible;overflow-wrap:anywhere}
.repo-facts{flex-wrap:wrap;row-gap:3px;overflow:visible}
.viewer-files{list-style:none;margin:0;padding:0;gap:0}
.viewer-files li{display:flex;align-items:baseline;justify-content:space-between;gap:16px;padding:12px 0;border-bottom:1px solid var(--hairline)}
.viewer-files .file-link{min-width:0;overflow-wrap:anywhere}
.viewer-files .size-num{flex:none;font-size:var(--t-sm)}
.viewer-search{margin-top:20px}
.viewer-summary{font-size:var(--t-sm)}
.viewer-files + .pagination{margin-top:24px}
@media(max-width:760px){
  .nav-links a,.user-menu a,.nav-right .btn{min-height:44px}
  .repo-tabs{overflow-x:auto;overflow-y:hidden;flex-wrap:nowrap}
  .repo-tabs .tab,.settings-nav .tab{min-height:44px;flex:none}
  .profile-grid{grid-template-columns:1fr}
  .scope-menu{left:0;right:auto}
  .scope-chips .chip{max-width:100%;overflow-wrap:anywhere}
  .pagination{flex-wrap:wrap}
  :where(#profile,#security,#api-tokens,#edit-scope){scroll-margin-top:150px}
}

.namespace-kind{color:var(--muted);margin:8px 0;font-size:var(--t-md)}
.token-create-form{grid-template-columns:minmax(160px,1fr) minmax(140px,1fr) minmax(120px,.6fr)}
.token-create-form .scope-field{grid-column:1/3;min-width:0}
.token-create-form>button{align-self:end}
@media(max-width:760px){
  .token-create-form{grid-template-columns:1fr}
  .token-create-form .scope-field{grid-column:auto}
  .repo-row .repo-cell{flex-wrap:wrap}
  .repo-row .repo-link{flex:1 1 160px;white-space:normal;overflow-wrap:anywhere}
}

@media(max-width:760px){
  header nav{display:grid;grid-template-columns:1fr auto;gap:4px}
  .nav-left{display:contents}
  .brand{grid-row:1;grid-column:1}
  .nav-right{grid-row:1;grid-column:2}
  .nav-links{grid-row:2;grid-column:1/-1;justify-content:space-between}
}

.tabs>.tab{color:var(--muted);opacity:1}
.tabs>.tab.tab-active{color:var(--accent-ink);font-weight:600}
.input::placeholder,.textarea::placeholder{color:var(--muted);opacity:1}
.commits-table td:nth-child(2){white-space:normal;overflow-wrap:anywhere;min-width:180px;max-width:420px}
@media(max-width:760px){.cli-copy,.token-copy,.row-actions .btn{min-width:44px;min-height:44px}}

.avatar-form{min-width:0}
.avatar-form label{flex:1 1 220px;min-width:0;flex-direction:column;align-items:flex-start;gap:8px}
.avatar-form input[type=file]{width:100%;min-width:0;max-width:100%}

@media(max-width:760px){
  .breadcrumbs>ul{flex-wrap:wrap;row-gap:8px;white-space:normal}
  .breadcrumbs li{min-width:0;overflow-wrap:anywhere}
}

/* Deployment workspace: status first, progressive disclosure for configuration. */
.deploy-page{max-width:1180px;margin-inline:auto}
.deploy-page .subhead{align-items:center}
.deploy-page .subhead-actions{flex-wrap:wrap;justify-content:flex-end}
.deploy-page .subhead p{margin:0}
.deploy-execution{display:flex;gap:12px;align-items:flex-start;border:1px solid var(--line);border-radius:var(--r-surface);background:var(--panel);padding:16px 20px;margin-bottom:20px}
.deploy-execution strong{color:var(--ink-strong)}
.deploy-execution p{margin:4px 0 0;color:var(--muted);font-size:var(--t-md)}
.deploy-status-dot{width:8px;height:8px;border-radius:50%;background:var(--warning);margin-top:7px;flex-shrink:0}
.deploy-nav{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:24px}
.deploy-nav a{padding:8px 12px;border-radius:var(--r-control);color:var(--muted);font-size:var(--t-md);text-decoration:none}
.deploy-nav a:hover{background:var(--panel2);color:var(--accent-ink)}
.deploy-metrics{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1px;border:1px solid var(--line);border-radius:var(--r-surface);overflow:hidden;background:var(--line);margin-bottom:20px}
.deploy-metrics>div{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:16px 20px;background:var(--panel)}
.deploy-metrics span{font-size:var(--t-md);color:var(--muted)}
.deploy-metrics strong{font-size:var(--t-2xl);font-weight:600;font-variant-numeric:tabular-nums}
.deploy-machines{display:grid;gap:16px;margin-bottom:24px;scroll-margin-top:24px}
.deploy-machine{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-surface);overflow:hidden}
.deploy-machine-head{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:20px 24px 12px}
.deploy-machine-head h2{margin:4px 0 0}
.deploy-machine-status{display:flex;flex-wrap:wrap;gap:8px 24px;padding:0 24px;color:var(--muted);font-size:var(--t-md)}
.deploy-healthy{color:var(--success)}
.deploy-model-chips{display:flex;flex-wrap:wrap;gap:8px;padding:16px 24px 20px}
.deploy-model-chips>span{display:flex;gap:8px;align-items:center;max-width:100%;background:var(--panel2);border-radius:var(--r-control);padding:6px 10px;overflow-wrap:anywhere}
.deploy-model-chips small{color:var(--muted);white-space:nowrap}
.deploy-machine-details{border-top:1px solid var(--hairline)}
.deploy-machine-details>summary{padding:12px 24px;color:var(--muted);font-size:var(--t-md);cursor:pointer}
.deploy-fold{display:block;background:var(--panel);border:1px solid var(--line);border-radius:var(--r-surface);margin:12px 0;overflow:clip;scroll-margin-top:24px}
.deploy-fold>summary,.deploy-task>summary{display:flex;align-items:center;gap:16px;list-style:none;cursor:pointer;padding:20px 24px;min-width:0}
.deploy-fold>summary::-webkit-details-marker,.deploy-task>summary::-webkit-details-marker{display:none}
.deploy-fold>summary::after,.deploy-task>summary::after{content:"";width:7px;height:7px;border-right:1.5px solid var(--muted);border-bottom:1.5px solid var(--muted);transform:rotate(45deg);flex-shrink:0;margin-left:8px;transition:transform .15s ease}
.deploy-fold[open]>summary::after,.deploy-task[open]>summary::after{transform:rotate(225deg)}
.deploy-fold[open]>summary{border-bottom:1px solid var(--hairline)}
.deploy-fold>summary:hover,.deploy-task>summary:hover{background:var(--row-hover)}
.deploy-fold-title{display:flex;flex-direction:column;gap:4px;flex:1;min-width:0}
.deploy-fold-title strong{font-weight:600;color:var(--ink);overflow-wrap:anywhere}
.deploy-fold-title small{font-size:var(--t-md);font-weight:400;color:var(--muted);overflow-wrap:anywhere}
.deploy-fold-body{padding:24px}
.deploy-fold-body>p:first-child{margin-top:0}
.deploy-step{display:grid;place-items:center;width:36px;height:36px;border-radius:var(--r-control);background:var(--panel2);color:var(--accent-ink);font-size:var(--t-md);font-weight:600;flex-shrink:0}
.deploy-kind,.deploy-count,.deploy-state{font-size:var(--t-sm);color:var(--muted);white-space:nowrap;background:var(--panel2);padding:4px 8px;border-radius:var(--r-control)}
.deploy-state-danger{color:var(--danger);background:var(--error-bg)}
.deploy-section{margin-top:28px;scroll-margin-top:24px}
.deploy-section-heading{display:flex;justify-content:space-between;align-items:center;gap:16px;margin-bottom:12px}
.deploy-section-heading h2{font-size:var(--t-lg);margin:0}
.deploy-section-heading p{margin:4px 0 0;font-size:var(--t-md)}
.deploy-section-heading>span{font-size:var(--t-md)}
.deploy-page form.deploy-form-grid,.deploy-field-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px;max-width:none;width:100%}
.deploy-form-grid>label,.deploy-field-grid>label{min-width:0;display:flex;flex-direction:column;gap:8px;color:var(--ink-label);font-size:var(--t-md)}
.deploy-form-grid .select,.deploy-form-grid .input{width:100%;max-width:100%;min-width:0;font-size:var(--t-base);text-overflow:ellipsis}
.deploy-form-grid>p,.deploy-form-grid>.deploy-span,.deploy-form-grid>.btn,.deploy-form-grid>.check{grid-column:1/-1}
.deploy-page .deploy-form-grid>.check{flex-direction:row;align-items:center}
.deploy-form-grid>p{font-size:var(--t-md);margin:0}
.deploy-page .deploy-options{margin:16px 0;border:1px solid var(--hairline);border-radius:var(--r-control);padding:12px 16px;background:var(--panel)}
.deploy-options>summary{cursor:pointer;color:var(--muted);font-size:var(--t-md)}
.deploy-options[open]>summary{margin-bottom:16px;color:var(--ink)}
.deploy-page .deploy-form-grid>.deploy-options{margin:0;background:var(--bg)}
.deploy-flow-note{font-size:var(--t-md)}
.deploy-page .deploy-task-list{padding:0}
.deploy-task{border-bottom:1px solid var(--hairline)}
.deploy-task:last-child{border-bottom:0}
.deploy-task>summary{padding:16px 24px;gap:12px}
.deploy-task>summary .deploy-fold-title strong{font-size:var(--t-base)}
.deploy-task>summary .deploy-fold-title small{font-size:var(--t-sm)}
.deploy-task-body{padding:4px 24px 24px;font-size:var(--t-md);overflow-wrap:anywhere}
.deploy-task-body .progress{width:100%;max-width:none;height:6px}
.deploy-task-list>p{padding:0 24px}
.deploy-kv{display:grid;grid-template-columns:auto minmax(0,1fr);gap:8px 16px}
.deploy-kv dt{color:var(--muted)}
.deploy-kv dd{margin:0;overflow-wrap:anywhere}
.deploy-error{color:var(--danger)}
.deploy-admin{margin-top:28px}
.deploy-footer{margin-top:24px;font-size:var(--t-sm)}
@media(max-width:760px){
 .deploy-page .subhead-actions{justify-content:flex-start}
 .deploy-metrics{grid-template-columns:repeat(2,minmax(0,1fr))}
 .deploy-page form.deploy-form-grid,.deploy-field-grid{grid-template-columns:minmax(0,1fr)}
 .deploy-fold>summary,.deploy-task>summary{padding:16px;gap:10px;flex-wrap:wrap}
 .deploy-fold-body{padding:16px}
 .deploy-machine-head{padding:16px 16px 12px}
 .deploy-machine-status{padding-inline:16px}
 .deploy-model-chips{padding:12px 16px 16px}
 .deploy-task-body{padding:4px 16px 16px}
 .deploy-section-heading{align-items:flex-start;flex-direction:column;gap:4px}
 .deploy-state{white-space:normal;max-width:100%}
 .deploy-nav{gap:0}
 .deploy-nav a{padding:8px}
}
@media(prefers-reduced-motion:reduce){.deploy-fold>summary::after,.deploy-task>summary::after{transition:none}}

.deploy-execution-enabled .deploy-status-dot{background:var(--success)}

.deploy-sync{margin:20px 0 0;font-size:var(--t-sm)}

.deploy-combo { border: 1px solid var(--hairline); border-radius: var(--r-control); padding: 16px; min-width: 0; }
.deploy-combo[hidden] { display: none; }
.deploy-combo legend { padding: 0 6px; font-weight: 600; }
.deploy-field-grid>.deploy-span,.deploy-field-grid>.check { grid-column: 1 / -1; }
.deploy-page .deploy-field-grid>.check { flex-direction: row; align-items: center; }
.deploy-combo>p { margin: 12px 0 0; font-size: var(--t-md); line-height: 1.6; }

.local-registration-table { width: 100%; min-width: 760px; table-layout: fixed; }
.local-registration-table th:first-child { width: 40%; }
.local-registration-table th:nth-child(2) { width: 21%; }
.local-registration-table th:nth-child(3) { width: 23%; }
.local-registration-table th:last-child { width: 16%; }
.table-wrap .local-registration-table td { white-space: normal; overflow-wrap: anywhere; }

.deploy-inline-source{padding:var(--s-4);border:1px solid var(--line);border-radius:var(--r-surface);background:var(--panel)}
.deploy-inline-source>.muted{margin:10px 0 0}

.deploy-inline-source [data-inline-choice][hidden]{display:none}
.deploy-page .deploy-section,.deploy-page .deploy-fold,.deploy-page .deploy-task{scroll-margin-top:88px}
@media(max-width:760px){.deploy-page .deploy-section,.deploy-page .deploy-fold,.deploy-page .deploy-task{scroll-margin-top:136px}}

/* Local Research account-choice layout. */
.mh-research-choice-page { min-height: 100svh; display: flex; align-items: flex-start; justify-content: center; padding: 24px 16px; }
.mh-research-choice-page .mh-auth-frame { width: min(640px, 100%); min-width: 0; margin: 0 auto; }
.mh-research-choice-page .mh-auth-brand { justify-content: flex-start; margin: 0 0 16px; font-size: 18px; }
.mh-research-choice-page .mh-auth-card { padding: 24px; }
.mh-research-choice-page h1 { font-size: 25px; line-height: 1.3; margin: 0 0 10px; }
.mh-research-choice-page .mh-auth-description { max-width: none; margin-bottom: 16px; font-size: 13px; }
.mh-research-choice-page .mh-auth-identity { padding: 12px 14px; margin-bottom: 18px; }
.mh-research-choice-page .mh-auth-form { gap: 12px; }
.mh-research-choice-page .mh-auth-foot { padding-top: 16px; margin-top: 18px; }
.mh-research-choice-page .mh-auth-bottom { margin-top: 12px; }
.mh-account-choice { border: 0; margin: 0; padding: 0; min-width: 0; }
.mh-account-choice legend { color: var(--muted); font-size: 12px; margin-bottom: 8px; }
.mh-account-choice input.mh-account-choice-toggle { position: absolute; opacity: 0; width: 1px; height: 1px; min-height: 0; margin: 0; padding: 0; border: 0; overflow: hidden; }
.mh-account-choice-options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-bottom: 20px; }
.mh-account-choice .mh-account-choice-option { display: flex; flex-direction: column; justify-content: center; min-height: 76px; border: 1px solid var(--line); border-radius: 8px; padding: 12px; color: var(--ink-strong); background: var(--panel); cursor: pointer; margin: 0; }
.mh-account-choice-option strong { font-size: 15px; font-weight: 650; }
.mh-account-choice-option span { display: block; font-size: 12px; font-weight: 400; color: var(--muted); margin-top: 3px; }
#mh-account-create:checked ~ .mh-account-choice-options [for=mh-account-create], #mh-account-bind:checked ~ .mh-account-choice-options [for=mh-account-bind] { border-color: var(--accent-ink); background: var(--panel2); box-shadow: inset 0 0 0 1px var(--accent-ink); }
#mh-account-create:focus-visible ~ .mh-account-choice-options [for=mh-account-create], #mh-account-bind:focus-visible ~ .mh-account-choice-options [for=mh-account-bind] { outline: 3px solid var(--accent-ink); outline-offset: 3px; }
#mh-account-create:checked ~ [data-choice=bind], #mh-account-bind:checked ~ [data-choice=create] { display: none; }
.mh-account-choice-panel { min-width: 0; }
.mh-account-choice-panel h2 { font-size: 16px; margin: 0 0 8px; }
.mh-account-choice-panel .mh-auth-button { background: var(--accent-fill); border-color: var(--accent-ink); color: var(--on-accent); }
@media (max-width: 540px) {
  .mh-research-choice-page { padding: 16px 12px; }
  .mh-research-choice-page .mh-auth-card { padding: 20px 16px; }
  .mh-research-choice-page h1 { font-size: 23px; }
  .mh-account-choice-options { gap: 8px; }
  .mh-account-choice .mh-account-choice-option { padding: 10px; }
}
@media (max-height: 700px) {
  .mh-research-choice-page { padding-top: 12px; }
  .mh-research-choice-page .mh-auth-brand { margin-bottom: 12px; }
  .mh-research-choice-page .mh-auth-description { margin-bottom: 12px; }
}

.mh-research-choice-page .mh-auth-heading { margin-bottom: 16px; }

/* Deployment target overview; each card leads to its own workspace. */
body:has(.deployment-overview){min-height:100vh;min-height:100dvh}
.deployment-overview{max-width:1180px;margin-inline:auto}
.deployment-overview-heading{align-items:center;gap:24px;margin-bottom:40px}
.deployment-overview-heading p{margin:8px 0 0}
.deployment-permission-module{display:flex;align-items:center;gap:14px;flex-shrink:0;padding:14px 18px;border:1px solid var(--line);border-radius:var(--r-surface);background:var(--panel);color:var(--ink);text-decoration:none}
.deployment-permission-module:hover{border-color:var(--accent-ink);background:var(--row-hover);text-decoration:none}
.deployment-permission-module>span:nth-child(2){display:flex;flex-direction:column;gap:4px}
.deployment-permission-module strong{font-size:var(--t-md);font-weight:600}
.deployment-permission-module small{color:var(--muted);font-size:var(--t-sm)}
.deployment-module-icon{display:grid;place-items:center;width:34px;height:34px;background:var(--panel2);color:var(--accent-ink);border-radius:var(--r-control)}
.deployment-module-icon svg{width:22px;height:22px}
.deployment-targets-heading{display:flex;align-items:center;gap:14px;margin-bottom:16px}
.deployment-targets-heading h2{font-size:var(--t-lg);margin:0}
.deployment-targets-heading>span{font-size:var(--t-sm);border-left:1px solid var(--line);padding-left:14px}
.deployment-target-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:24px}
.deployment-target-card{display:flex;flex-direction:column;min-width:0;padding:26px 28px 0;background:var(--panel);border:1px solid var(--line);border-radius:var(--r-surface);color:var(--ink);text-decoration:none;overflow:hidden;transition:border-color .15s,box-shadow .15s,transform .15s}
.deployment-target-card:hover{border-color:var(--accent-ink);box-shadow:0 8px 24px rgba(31,56,97,.08);transform:translateY(-2px);text-decoration:none}
.deployment-target-card:focus-visible,.deployment-permission-module:focus-visible{outline:2px solid var(--accent-ink);outline-offset:4px}
.deployment-target-top{display:flex;align-items:center;justify-content:space-between;gap:16px}
.deployment-target-icon{display:grid;place-items:center;width:48px;height:48px;border-radius:12px;background:var(--panel2);color:var(--accent-ink)}
.deployment-target-icon svg{width:30px;height:30px}
.deployment-target-identity{margin-top:22px}
.deployment-target-identity h3{font-size:30px;line-height:1.2;letter-spacing:-.02em;margin:7px 0 8px;font-weight:650;color:var(--ink-strong)}
.deployment-target-identity p{margin:0;color:var(--muted);font-size:var(--t-md)}
.deployment-target-health{display:flex;align-items:center;gap:8px;margin-top:22px;font-size:var(--t-md);color:var(--muted)}
.deployment-health-dot{width:7px;height:7px;border-radius:50%;background:var(--warning);flex-shrink:0}
.deployment-health-dot.is-healthy{background:var(--success)}
.deployment-target-resources{display:flex;gap:24px;margin-top:22px;font-size:var(--t-md);color:var(--muted)}
.deployment-target-resources strong{color:var(--ink);font-weight:600}
.deployment-target-models{display:flex;flex-direction:column;gap:8px;min-height:68px;margin:14px 0 24px}
.deployment-target-models>span{display:flex;align-items:baseline;gap:10px;min-width:0;overflow-wrap:anywhere}
.deployment-target-models small{min-width:32px;color:var(--muted);font-size:var(--t-sm)}
.deployment-target-models code{font-size:var(--t-md);overflow-wrap:anywhere}
.deployment-target-footer{display:flex;align-items:center;justify-content:space-between;gap:16px;margin:0 -28px;padding:16px 28px;border-top:1px solid var(--hairline);font-size:var(--t-md);font-weight:600;color:var(--accent-ink);margin-top:auto}
.deployment-target-empty{grid-column:1/-1;border:1px dashed var(--line);border-radius:var(--r-surface);padding:40px;text-align:center;background:var(--panel)}
.deploy-breadcrumbs{margin-bottom:8px}
.deployment-overview .deploy-sync{margin-top:22px;font-size:var(--t-sm)}
@media(max-width:760px){.deployment-overview-heading{align-items:flex-start;flex-direction:column;margin-bottom:28px}.deployment-permission-module{align-self:stretch}.deployment-permission-module>span:last-child{margin-left:auto}.deployment-target-grid{grid-template-columns:minmax(0,1fr);gap:16px}.deployment-target-card{padding:22px 22px 0}.deployment-target-footer{margin-inline:-22px;padding-inline:22px}.deployment-target-empty{padding:28px 20px}}
@media(prefers-reduced-motion:reduce){.deployment-target-card{transition:none}.deployment-target-card:hover{transform:none}}

/* Deployment authorization is scoped to one, several, or every channel. */
.card form.deployment-permission-form{max-width:none;width:100%}
[data-deployment-permission-form] [hidden]{display:none!important}
.deployment-permission-username{max-width:520px}
.deployment-permission-scope,.deployment-permission-channels{border:0;padding:0;margin:4px 0;min-width:0}
.deployment-permission-scope legend,.deployment-permission-channels legend{font-weight:600;margin-bottom:12px;color:var(--ink-label)}
.deployment-scope-options{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}
.deployment-channel-options{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
.deployment-scope-option,.deployment-channel-option{display:flex;flex-direction:row;gap:12px;align-items:flex-start;border:1px solid var(--line);background:var(--panel);border-radius:var(--r-surface);padding:16px;cursor:pointer;min-width:0}
.deployment-scope-option:has(input:checked),.deployment-channel-option:has(input:checked){border-color:var(--accent-ink);background:var(--panel2)}
.deployment-scope-option>input,.deployment-channel-option>input{flex-shrink:0;margin-top:2px}
.deployment-scope-option>span,.deployment-channel-option>span{display:flex;flex-direction:column;gap:5px;min-width:0}
.deployment-scope-option strong,.deployment-channel-option strong{font-weight:600;font-size:var(--t-base)}
.deployment-scope-option small,.deployment-channel-option small{font-size:var(--t-sm);color:var(--muted);font-weight:400}
.deployment-channel-tags,.deployment-permission-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
@media(max-width:760px){.deployment-scope-options,.deployment-channel-options{grid-template-columns:minmax(0,1fr)}.deployment-permission-actions{align-items:flex-start;flex-direction:column}}

/* External repository imports share the repository palette and leave forms stable while polling. */
.external-sync .sync-nav{display:flex;gap:24px;flex-wrap:wrap;margin:24px 0}
.sync-section{margin:24px 0;scroll-margin-top:88px}.sync-section>summary,.sync-collection>summary{cursor:pointer;padding:20px 24px;display:list-item;list-style-position:inside}.sync-section>summary strong{margin-right:16px}.sync-section>summary>.muted,.sync-collection>summary>.muted{font-size:13px}
.sync-body{padding:0 24px 24px}.external-sync form.sync-form{width:100%;max-width:none;display:grid;gap:16px;margin:16px 0}.sync-form label{display:grid;gap:8px;min-width:0}.sync-form input:not([type=checkbox]),.sync-form select,.sync-form textarea{width:100%;max-width:none}.sync-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}.sync-wide{grid-column:1/-1}.sync-form>.btn{justify-self:start}
.sync-options{background:var(--panel2);border:1px solid var(--line);padding:16px;border-radius:8px}.sync-options>summary{cursor:pointer}.sync-options[open]>summary{margin-bottom:12px}.sync-preview{border-left:3px solid var(--accent);background:var(--panel2);padding:20px 24px;border-radius:6px;margin-top:24px}.sync-preview code,.sync-phase,.sync-source h3,.sync-job-heading strong{overflow-wrap:anywhere}.sync-collection{border:1px solid var(--line);border-radius:8px;margin-top:20px}.sync-collection>summary>.muted{margin-left:16px}.sync-actions{display:flex;gap:16px;align-items:center;flex-wrap:wrap}.sync-actions form{margin:0}.sync-members{min-width:620px}.sync-members td{vertical-align:middle}.sync-members input:not([type=checkbox]){min-width:180px}.sync-members td:nth-child(2){overflow-wrap:anywhere}
.sync-source-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}.sync-source{padding:24px;min-width:0}.sync-source h3{font-size:17px;margin:12px 0}.sync-source form{margin-top:auto}.sync-source .sync-actions{justify-content:space-between}.sync-job{padding:20px 24px;margin:12px 0}.sync-job-heading{display:flex;justify-content:space-between;align-items:baseline;gap:16px}.sync-job progress{width:100%;height:6px;margin:8px 0 12px}.sync-state{white-space:nowrap;font-size:12px;font-weight:600}.sync-succeeded,.sync-unchanged{color:var(--success)}.sync-failed{color:var(--danger)}.sync-running{color:var(--accent)}.sync-queued{color:var(--muted)}.sync-job .error{margin:12px 0}.sync-job form{margin-top:16px}.sync-provenance{background:var(--panel2);border:1px solid var(--line);padding:16px;border-radius:8px;margin:16px 0;overflow-wrap:anywhere}
@media(max-width:680px){.sync-grid,.sync-source-grid{grid-template-columns:1fr}.sync-job-heading{display:block}.sync-job-heading .sync-state{display:block;margin-top:8px}.sync-section>summary>.muted{display:block;margin:8px 0 0 20px}.sync-body{padding:0 16px 16px}.sync-section>summary,.sync-source,.sync-job{padding:16px}.sync-preview{padding:16px}.sync-collection>summary>.muted{display:block;margin-top:8px}.external-sync .subhead{gap:12px;flex-wrap:wrap}}

@media(max-width:760px){.external-sync .sync-section{scroll-margin-top:136px}}

.external-sync [data-sync-panel][hidden]{display:none!important}
.external-sync .sync-tabs{gap:4px;flex-wrap:nowrap;overflow-x:auto;border-bottom:1px solid var(--line);padding:0 0 4px;margin:24px 0}
.external-sync .sync-tabs [role="tab"]{flex-shrink:0;padding:12px 16px;border-radius:8px 8px 0 0;color:var(--muted);text-decoration:none;border-bottom:3px solid transparent;font-weight:600;white-space:nowrap}
.external-sync .sync-tabs [aria-selected="true"]{color:var(--accent);background:var(--panel);border-bottom-color:currentColor}
.external-sync .sync-tabs [role="tab"]:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.sync-panel-heading{padding:24px 24px 8px}.sync-panel-heading h2{margin:0 0 8px}
@media(max-width:680px){.sync-panel-heading{padding:16px 16px 8px}.external-sync .sync-tabs [role="tab"]{padding:10px 12px}}
