/* ── 墨与瓷 · shared components ────────────────────────────────────────── Global building blocks for the app shell and the workspace pages. Every value comes from design-tokens.css so both themes stay in step. */ /* ── Icon sizing (inline SVG) ─────────────────────────────────────────── */ .icon { width: 18px; height: 18px; flex: none; stroke: currentColor; fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; } .icon-sm { width: 15px; height: 15px; } .icon-xs { width: 13px; height: 13px; } /* ── Seal & wordmark ──────────────────────────────────────────────────── */ .seal { --s: 30px; width: var(--s); height: var(--s); flex: none; display: grid; place-items: center; background: var(--vermilion); color: var(--seal-fg); border-radius: 5px; font-family: var(--font-serif); font-weight: 700; font-size: calc(var(--s) * 0.56); line-height: 1; position: relative; box-shadow: 0 1px 0 rgba(255, 255, 255, 0.18) inset, 0 6px 16px -8px color-mix(in srgb, var(--vermilion) 70%, transparent); } .seal::before { content: ''; position: absolute; inset: 2.5px; border: 1px solid color-mix(in srgb, var(--seal-fg) 55%, transparent); border-radius: 3px; } .wordmark { font-family: var(--font-num); font-size: 19px; font-weight: 500; letter-spacing: -0.01em; line-height: 1; } .wordmark i { font-style: italic; font-weight: 400; color: var(--vermilion); } /* ── Buttons ──────────────────────────────────────────────────────────── */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 40px; padding: 0 18px; border-radius: var(--radius-btn); font-family: var(--font-sans); font-size: 14px; font-weight: 600; letter-spacing: 0.02em; white-space: nowrap; line-height: 1.4; border: 1px solid transparent; cursor: pointer; background: var(--primary-bg); color: var(--primary-fg); box-shadow: 0 1px 0 rgba(255, 255, 255, 0.12) inset, 0 8px 20px -10px rgba(22, 23, 26, 0.55); transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast), transform var(--transition-fast), box-shadow var(--transition-fast), opacity var(--transition-fast); } .btn:active { transform: translateY(1px); } .btn:focus-visible { outline: none; box-shadow: var(--ring-focus); } .btn:disabled { opacity: 0.4; cursor: not-allowed; transform: none; } .btn-primary { background: var(--primary-bg); color: var(--primary-fg); border-color: transparent; box-shadow: 0 1px 0 rgba(255, 255, 255, 0.12) inset, 0 8px 20px -10px rgba(22, 23, 26, 0.55); } .btn-primary:hover:not(:disabled) { background: var(--primary-hover); opacity: 1; } .btn-secondary { background: var(--surface); color: var(--text); border: 1px solid var(--line-2); box-shadow: none; } .btn-secondary:hover:not(:disabled) { border-color: var(--line-3); } .btn-ghost { background: var(--surface); color: var(--text); border: 1px solid var(--line-2); box-shadow: none; } .btn-ghost:hover:not(:disabled) { border-color: var(--line-3); background: var(--surface); } .btn-quiet { background: transparent; color: var(--text2); border-color: transparent; box-shadow: none; } .btn-quiet:hover:not(:disabled) { background: var(--surface); } .btn-danger { background: var(--surface); color: var(--vermilion); border: 1px solid var(--vermilion-line); box-shadow: none; } .btn-danger:hover:not(:disabled) { background: var(--vermilion-soft); border-color: var(--vermilion-line); } .btn-sm { height: 32px; padding: 0 12px; font-size: 13px; border-radius: var(--radius-sm); } .btn-lg { height: 48px; padding: 0 22px; font-size: 15px; } .btn-block { width: 100%; } /* Loading state */ .btn.loading { position: relative; color: transparent !important; } .btn.loading::after { content: ''; position: absolute; width: 16px; height: 16px; top: 50%; left: 50%; margin: -8px 0 0 -8px; border: 2px solid var(--o30); border-right-color: var(--primary-fg); border-radius: 50%; animation: button-loading-spinner 0.75s linear infinite; } @keyframes button-loading-spinner { to { transform: rotate(360deg); } } /* ── Chips ────────────────────────────────────────────────────────────── */ .chip { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 9px; border-radius: var(--radius-pill); font-size: 12px; font-weight: 500; white-space: nowrap; background: var(--surface-2); color: var(--text2); border: 1px solid var(--line); } .chip .d { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; } .chip-ai { background: var(--celadon-soft); border-color: var(--celadon-line); color: var(--celadon); } .chip-wait { background: var(--vermilion-soft); border-color: var(--vermilion-line); color: var(--vermilion); } .chip-human { background: var(--ink); border-color: var(--ink); color: var(--primary-fg); } .chip-brass { background: var(--brass-soft); border-color: var(--brass-line); color: var(--brass); } .chip-quiet { background: transparent; } .chip-sq { border-radius: var(--radius-chip); } /* ── Avatars ──────────────────────────────────────────────────────────── */ .avatar { --a: 34px; width: var(--a); height: var(--a); flex: none; border-radius: 50%; display: grid; place-items: center; font-family: var(--font-serif); font-weight: 600; font-size: calc(var(--a) * 0.4); color: var(--ink); background: var(--surface-2); border: 1px solid var(--line-2); position: relative; } .avatar.ink { background: var(--ink); color: var(--primary-fg); border-color: var(--ink); } .avatar.celadon { background: var(--celadon-soft); color: var(--celadon); border-color: var(--celadon-line); } .avatar.brass { background: var(--brass-soft); color: var(--brass); border-color: var(--brass-line); } .avatar.vermilion { background: var(--vermilion-soft); color: var(--vermilion); border-color: var(--vermilion-line); } .avatar .presence-dot { position: absolute; right: -1px; bottom: -1px; width: 10px; height: 10px; border-radius: 50%; background: var(--celadon); border: 2px solid var(--surface); } .avatar-sm { --a: 26px; } .avatar-lg { --a: 52px; } /* ── Cards ────────────────────────────────────────────────────────────── */ .card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); box-shadow: var(--shadow-md); padding: var(--space-xl); width: 100%; max-width: 480px; margin: 0 auto; } .card-full { max-width: none; } .panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); box-shadow: var(--shadow-md); } .panel-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 20px 24px 0; } .panel-body { padding: 20px 24px 24px; } .panel-note { font-size: 12.5px; color: var(--muted); } /* ── Page header ──────────────────────────────────────────────────────── */ .eyebrow { display: flex; align-items: center; gap: 10px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--muted); margin-bottom: 14px; } .eyebrow::before { content: ''; width: 18px; height: 1px; background: var(--vermilion); } .page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 32px; padding-bottom: 28px; margin-bottom: 32px; border-bottom: 1px solid var(--line); } .title { font-family: var(--font-serif); font-size: 36px; font-weight: 600; letter-spacing: 0.02em; line-height: 1.15; } .lede { margin-top: 12px; max-width: 60ch; color: var(--muted); font-size: 14.5px; line-height: 1.75; } .actions { display: flex; align-items: center; gap: 10px; flex: none; } .section-title { font-family: var(--font-serif); font-size: 17px; font-weight: 600; letter-spacing: 0.02em; } /* ── Segmented & tabs ─────────────────────────────────────────────────── */ .seg { display: inline-flex; padding: 3px; gap: 2px; border-radius: var(--radius-md); background: var(--surface-sunk); border: 1px solid var(--line); } .seg button { white-space: nowrap; height: 30px; padding: 0 13px; border-radius: 7px; font-size: 13px; color: var(--muted); display: inline-flex; align-items: center; gap: 7px; border: 0; background: none; cursor: pointer; transition: all var(--t-fast); } .seg button:hover { color: var(--ink); } .seg button[aria-selected='true'] { background: var(--surface); color: var(--ink); font-weight: 600; box-shadow: var(--shadow-sm), 0 0 0 1px var(--line); } .seg .count { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; } .seg [aria-selected='true'] .count.alert { color: var(--vermilion); } .tabs { display: flex; gap: 30px; border-bottom: 1px solid var(--line); margin-bottom: 28px; } .tabs button { position: relative; padding: 0 0 13px; font-size: 14.5px; color: var(--muted); display: inline-flex; align-items: center; gap: 8px; border: 0; background: none; cursor: pointer; transition: color var(--t-fast); } .tabs button:hover { color: var(--ink); } .tabs button[aria-selected='true'] { color: var(--ink); font-weight: 600; } .tabs button[aria-selected='true']::after { content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--ink); } .tabs .count { font-size: 11.5px; color: var(--faint); font-variant-numeric: tabular-nums; font-weight: 500; } /* ── Stat strip (one container, hairline-divided) ─────────────────────── */ .stats { display: grid; grid-template-columns: repeat(var(--cols, 4), minmax(0, 1fr)); background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); box-shadow: var(--shadow-md); margin-bottom: 28px; } .stat { padding: 22px 26px; position: relative; } .stat + .stat::before { content: ''; position: absolute; left: 0; top: 22px; bottom: 22px; width: 1px; background: var(--line); } .stat-label { font-size: 12.5px; color: var(--muted); letter-spacing: 0.06em; display: flex; align-items: center; gap: 8px; } .stat-value { margin-top: 12px; font-family: var(--font-num); font-weight: 380; font-size: 42px; line-height: 1; letter-spacing: -0.02em; font-variant-numeric: lining-nums tabular-nums; display: flex; align-items: baseline; gap: 6px; } .stat-value small { font-size: 17px; color: var(--muted); font-weight: 400; letter-spacing: 0; } .stat-foot { margin-top: 12px; font-size: 12.5px; color: var(--muted); display: flex; align-items: center; gap: 8px; } .delta { display: inline-flex; align-items: center; gap: 3px; font-weight: 600; font-variant-numeric: tabular-nums; } .delta.up { color: var(--celadon); } .delta.down { color: var(--vermilion); } /* ── Table ────────────────────────────────────────────────────────────── */ .table { width: 100%; border-collapse: collapse; } .table th { text-align: left; font-weight: 500; font-size: 12px; letter-spacing: 0.08em; color: var(--muted); padding: 14px 18px; border-bottom: 1px solid var(--line); background: var(--surface-2); } .table th:first-child { border-top-left-radius: var(--radius-card); padding-left: 24px; } .table th:last-child { border-top-right-radius: var(--radius-card); } .table td { padding: 16px 18px; border-bottom: 1px solid var(--line); vertical-align: middle; } .table td:first-child { padding-left: 24px; } .table tr:last-child td { border-bottom: 0; } .table tbody tr { transition: background-color var(--t-fast); } .table tbody tr:hover { background: var(--surface-2); } .table .right { text-align: right; } .person { display: flex; align-items: center; gap: 12px; } .person-name { font-weight: 600; font-size: 14px; line-height: 1.35; } .person-sub { font-size: 12px; color: var(--muted); line-height: 1.35; } /* Load meter: five pips */ .pips { display: inline-flex; gap: 3px; vertical-align: middle; } .pips i { width: 6px; height: 16px; border-radius: 2px; background: var(--line-2); } .pips i.on { background: var(--celadon); } .stars { display: inline-flex; gap: 2px; color: var(--brass); } .stars .icon { width: 14px; height: 14px; fill: currentColor; stroke-width: 1; } .stars .off { fill: none; color: var(--line-3); } /* ── Inputs ───────────────────────────────────────────────────────────── */ .field { display: flex; flex-direction: column; gap: 8px; } .field label { font-size: 13px; font-weight: 600; color: var(--text2); letter-spacing: 0.04em; } .input { height: 48px; padding: 0 16px; border-radius: var(--radius-input); border: 1px solid var(--line-2); background: var(--surface); color: var(--text); outline: none; font: inherit; font-size: 15px; transition: border-color var(--t-fast), box-shadow var(--t-fast); } .input::placeholder { color: var(--faint); } .input:hover { border-color: var(--line-3); } .input:focus { border-color: var(--ink); box-shadow: var(--ring); } /* Legacy form primitives */ .form-group { margin-bottom: var(--space-lg); width: 100%; } .form-label { display: block; margin-bottom: 9px; font-weight: var(--font-weight-medium); color: var(--text3); font-size: 13.5px; } .form-input { width: 100%; padding: 14px 16px; font-family: var(--font-sans); font-size: var(--text-base); background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--radius-input); color: var(--text); transition: border-color var(--transition-fast), box-shadow var(--transition-fast); } .form-input::placeholder { color: var(--faint); } .form-input:hover { border-color: var(--line-3); } .form-input:focus, .form-input:focus-visible { border-color: var(--ink); box-shadow: var(--ring-focus); outline: none; } .form-input:disabled { background: var(--o04); color: var(--muted); cursor: not-allowed; } .form-input.error, .form-input[aria-invalid='true'] { border-color: var(--error-color); } .form-input.error:focus, .form-input[aria-invalid='true']:focus { box-shadow: 0 0 0 3px var(--error-bg); } /* ── Charts ───────────────────────────────────────────────────────────── */ .viz { position: relative; } .viz svg { display: block; width: 100%; height: auto; overflow: visible; } .viz-tip { position: absolute; pointer-events: none; opacity: 0; z-index: 5; min-width: 96px; padding: 8px 11px; border-radius: 9px; background: var(--ink); color: var(--primary-fg); box-shadow: var(--shadow-lg); font-size: 12px; line-height: 1.5; transition: opacity var(--t-fast); white-space: nowrap; } .viz-tip .k { display: block; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.06em; opacity: 0.65; } .viz-tip .v { font-family: var(--font-num); font-size: 18px; } .viz-tip .v i { font-style: normal; font-size: 11px; opacity: 0.65; font-family: var(--font-sans); } .viz-tip .row { display: flex; align-items: center; gap: 7px; margin-top: 3px; } .viz-tip .row i { width: 8px; height: 8px; border-radius: 2px; flex: none; } .viz-tip .row b { margin-left: auto; padding-left: 12px; font-variant-numeric: tabular-nums; } .legend { display: flex; align-items: center; gap: 18px; font-size: 12.5px; color: var(--muted); } .legend span { display: inline-flex; align-items: center; gap: 7px; } .legend i { width: 9px; height: 9px; border-radius: 2px; flex: none; } .legend .l1 { background: var(--viz-1); } .legend .l2 { background: var(--viz-2); } .viz-bars { display: flex; flex-direction: column; gap: 14px; padding: 4px 0 2px; } .vb-row { display: grid; grid-template-columns: 54px minmax(0, 1fr) 52px; align-items: center; gap: 14px; font-size: 13px; } .vb-label { color: var(--muted); display: inline-flex; align-items: center; gap: 5px; } .vb-label .icon { width: 12px; height: 12px; fill: currentColor; color: var(--brass); stroke-width: 1; } .vb-track { height: 12px; border-radius: 4px; background: var(--surface-sunk); overflow: hidden; } .vb-fill { display: block; height: 100%; border-radius: 4px; background: var(--brass); transition: width 0.9s var(--ease); } .vb-value { text-align: right; font-size: 17px; font-variant-numeric: tabular-nums; } .vb-value i { font-style: normal; font-size: 11px; color: var(--muted); margin-left: 2px; font-family: var(--font-sans); } /* ── Toast ────────────────────────────────────────────────────────────── */ .toast { position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 20px); opacity: 0; pointer-events: none; z-index: 100; display: flex; align-items: center; gap: 10px; padding: 11px 18px; border-radius: var(--radius-pill); background: var(--ink); color: var(--primary-fg); font-size: 13.5px; box-shadow: var(--shadow-lg); transition: opacity var(--t-med), transform var(--t-med); } .toast.show { opacity: 1; transform: translate(-50%, 0); } .toast .seal { --s: 18px; border-radius: 3px; } .toast .seal::before { inset: 1.5px; border-radius: 2px; } /* ── Load-in choreography ─────────────────────────────────────────────── */ .reveal { opacity: 0; transform: translateY(10px); animation: reveal 0.7s var(--ease) forwards; animation-delay: calc(var(--i, 0) * 70ms + 60ms); } @keyframes reveal { to { opacity: 1; transform: none; } } @media (prefers-reduced-motion: reduce) { .reveal { animation: none; opacity: 1; transform: none; } .pulse::after { animation: none; } * { transition-duration: 0s !important; } } /* ── Stepper ──────────────────────────────────────────────────────────── */ .progress-steps { display: flex; justify-content: center; align-items: flex-start; gap: var(--space-2xl); margin-bottom: var(--space-2xl); } .progress-step { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--space-md); width: 140px; } .step-indicator { width: 40px; height: 40px; border-radius: var(--radius-full); background: var(--o05); border: 2px solid var(--o14); color: var(--muted); display: flex; align-items: center; justify-content: center; font-weight: var(--font-weight-semibold); font-family: var(--font-display); transition: background-color var(--transition-normal), border-color var(--transition-normal), color var(--transition-normal); } .step-indicator.active { background: var(--accent-bg-12); border-color: var(--accent-ink); color: var(--accent-ink); } .step-indicator.completed { background: var(--accent-solid); border-color: var(--accent-ink); color: var(--on-accent-solid); } .step-details h3 { font-size: var(--text-base); font-family: var(--font-display); margin-bottom: var(--space-xs); color: var(--text); } .step-details p { font-size: var(--text-sm); color: var(--muted); } @media (max-width: 768px) { .progress-steps { flex-direction: column; align-items: flex-start; gap: var(--space-lg); } .progress-step { flex-direction: row; width: 100%; text-align: left; } .step-details { flex: 1; } } /* Modal buttons. Global rather than scoped because BaseModal takes its actions through a slot, and slot content is styled by the parent — three modals were each carrying a byte-identical private copy of these rules. Distinct from .btn above, which is the app's louder primary action: these are the quieter Cancel/Confirm pair a dialog footer wants. */ .modal-btn { padding: 9px 16px; border-radius: var(--radius-btn, 8px); font-size: 14px; font-weight: 600; cursor: pointer; border: 1px solid var(--border-color); background: var(--background-soft); color: inherit; } .modal-btn-primary { background: var(--accent-solid); color: var(--on-accent-solid); border-color: transparent; } .modal-btn-danger { background: var(--c-danger, var(--danger)); color: var(--on-accent-solid); border-color: transparent; } .modal-btn:disabled { opacity: 0.6; cursor: not-allowed; } /* Native checkboxes/radios follow the design accent instead of the browser default (blue), so form controls match the theme app-wide. */ input[type='checkbox'], input[type='radio'] { accent-color: var(--accent-ink); } /* Nav section heading — shared by the desktop sidebar and the mobile More sheet so the two menus can't drift apart visually. */ .nav-section-heading { color: var(--faint); font-family: var(--font-mono); font-size: 11px; font-weight: var(--font-weight-medium); text-transform: uppercase; letter-spacing: 0.1em; } /* ── Responsive table → cards ──────────────────────────────────────────── Desktop keeps its own grid template; below 768px each row becomes a card: the primary cell and a trailing badge share line 1, and the remaining values wrap onto line 2 carrying their own labels (the table header is hidden, so each value has to name itself). Markup: .rcards-head on the header row, .rcards-row on each row, .rcards-primary / .rcards-badge on the line-1 cells, and .rcards-meta wrapping a .rcards-label + .rcards-value pair on every other cell. The consuming component must scope its desktop grid to @media (min-width: 769px) — a scoped SFC rule carries a [data-v-*] attribute and would otherwise outrank these global classes. */ .rcards-label { display: none; } @media (max-width: 768px) { .rcards-head { display: none; } .rcards-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; } /* Zero-height full-width break: pushes the meta cells to their own line without assuming how wide the badge renders */ .rcards-row::after { content: ''; order: 3; flex: 1 0 100%; height: 0; } .rcards-primary { flex: 1 1 auto; min-width: 0; order: 1; } .rcards-badge { flex: 0 0 auto; margin-left: auto; order: 2; } .rcards-meta { order: 4; flex: 0 1 auto; min-width: 0; max-width: 100%; display: inline-flex; align-items: baseline; gap: 4px; font-size: 12px; color: var(--muted); } .rcards-label { display: inline; font-size: 10.5px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--faint); } /* text-overflow needs its own block box — it does nothing on a flex item */ .rcards-value { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } } /* ── App shell (sidebar + topbar) ───────────────────────────────────────── Scoped to .rp-shell so the widget and embed surfaces never inherit it. */ .rp-shell { display: grid; grid-template-columns: 244px minmax(0, 1fr); height: 100vh; overflow: hidden; background: var(--paper); color: var(--ink); } .rp-shell .sidebar { background: var(--paper-2); border-right: 1px solid var(--line); display: flex; flex-direction: column; min-height: 0; } .rp-shell .brand { display: flex; align-items: center; gap: 12px; padding: 22px 22px 20px; } .rp-shell .brand-text { display: flex; flex-direction: column; gap: 5px; min-width: 0; } .rp-shell .brand-sub { font-size: 11px; color: var(--muted); letter-spacing: 0.32em; white-space: nowrap; } .rp-shell .nav { flex: 1; overflow-y: auto; padding: 6px 14px 14px; } .rp-shell .nav-label { display: flex; align-items: baseline; justify-content: space-between; padding: 18px 10px 8px; font-size: 11.5px; color: var(--muted); letter-spacing: 0.24em; } .rp-shell .nav-label em { font-style: normal; font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--faint); } .rp-shell .nav-item { display: flex; align-items: center; gap: 12px; height: 38px; padding: 0 10px; margin: 1px 0; border-radius: var(--radius-md); color: var(--text2); font-size: 14px; position: relative; transition: background-color var(--t-fast), color var(--t-fast); } .rp-shell .nav-item .icon { color: var(--muted); transition: color var(--t-fast); } .rp-shell .nav-item:hover { background: color-mix(in srgb, var(--surface) 60%, transparent); color: var(--ink); } .rp-shell .nav-item[aria-current='page'] { background: var(--surface); color: var(--ink); font-weight: 600; box-shadow: var(--shadow-sm), 0 0 0 1px var(--line); } .rp-shell .nav-item[aria-current='page'] .icon { color: var(--vermilion); } .rp-shell .nav-item .nav-badge { margin-left: auto; } .rp-shell .nav-badge { min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--radius-pill); display: inline-grid; place-items: center; font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums; background: var(--line); color: var(--text2); } .rp-shell .nav-badge.alert { background: var(--vermilion); color: var(--seal-fg); } .rp-shell .nav-sub { overflow: hidden; display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--t-med); } .rp-shell .nav-sub > div { min-height: 0; } .rp-shell .nav-group.open .nav-sub { grid-template-rows: 1fr; } .rp-shell .nav-group .chev { margin-left: auto; color: var(--faint); transition: transform var(--t-med); } .rp-shell .nav-group.open .chev { transform: rotate(90deg); } .rp-shell .nav-sub .nav-item { padding-left: 40px; height: 34px; font-size: 13.5px; color: var(--muted); } .rp-shell .sidebar-foot { padding: 14px; border-top: 1px solid var(--line); } .rp-shell .me { display: flex; align-items: center; gap: 11px; padding: 8px; border-radius: var(--radius-md); transition: background-color var(--t-fast); } .rp-shell .me:hover { background: color-mix(in srgb, var(--surface) 60%, transparent); } .rp-shell .me-name { font-size: 13.5px; font-weight: 600; line-height: 1.3; } .rp-shell .me-role { font-size: 12px; color: var(--muted); line-height: 1.3; } .rp-shell .me .icon { margin-left: auto; color: var(--faint); } .rp-shell .main { display: flex; flex-direction: column; min-width: 0; min-height: 0; } .rp-shell .topbar { height: 64px; flex: none; display: flex; align-items: center; gap: 14px; padding: 0 28px; border-bottom: 1px solid var(--line); background: color-mix(in srgb, var(--paper) 88%, transparent); backdrop-filter: blur(10px); } .rp-shell .crumb { display: flex; align-items: center; gap: 10px; font-size: 13.5px; color: var(--muted); min-width: 0; white-space: nowrap; overflow: hidden; } .rp-shell .crumb b { color: var(--ink); font-weight: 600; } .rp-shell .crumb .en { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--faint); } .rp-shell .crumb .sep { color: var(--line-3); } .rp-shell .topbar-spacer { flex: 1; } kbd { font-family: var(--font-mono); font-size: 10.5px; padding: 2px 6px; border-radius: 5px; background: var(--surface-2); border: 1px solid var(--line-2); color: var(--muted); line-height: 1.4; } .rp-shell .presence { display: inline-flex; align-items: center; gap: 9px; height: 38px; padding: 0 14px 0 12px; border-radius: var(--radius-pill); border: 1px solid var(--celadon-line); background: var(--celadon-soft); color: var(--celadon); font-size: 13px; font-weight: 600; transition: all var(--t-fast); } .rp-shell .presence[data-state='away'] { border-color: var(--line-2); background: var(--surface); color: var(--muted); } .rp-shell .presence[data-state='away'] .pulse { background: var(--faint); } .rp-shell .presence[data-state='away'] .pulse::after { display: none; } .pulse { width: 7px; height: 7px; border-radius: 50%; background: currentColor; position: relative; flex: none; } .pulse::after { content: ''; position: absolute; inset: -4px; border-radius: 50%; border: 1.5px solid currentColor; opacity: 0; animation: pulse 2.4s var(--ease) infinite; } @keyframes pulse { 0% { transform: scale(0.5); opacity: 0.7; } 100% { transform: scale(1.5); opacity: 0; } } .icon-btn { width: 38px; height: 38px; flex: none; border-radius: var(--radius-md); display: grid; place-items: center; color: var(--text2); border: 1px solid transparent; background: none; cursor: pointer; position: relative; transition: background-color var(--t-fast), border-color var(--t-fast); } .icon-btn:hover { background: var(--surface); border-color: var(--line); } .icon-btn .dot { position: absolute; top: 9px; right: 10px; width: 7px; height: 7px; border-radius: 50%; background: var(--vermilion); box-shadow: 0 0 0 2px var(--paper); } .icon-btn.bordered { border-color: var(--line); background: var(--surface); } .icon-btn.sm { width: 32px; height: 32px; border-radius: var(--radius-sm); } .rp-shell .page { flex: 1; overflow-y: auto; min-height: 0; } .rp-shell .page-inner { max-width: 1320px; margin: 0 auto; padding: 0 0 32px; } /* Icon rail — workspace pages and narrow screens */ .rp-shell.rail { grid-template-columns: 72px minmax(0, 1fr); } .rp-shell.rail .brand { justify-content: center; padding: 22px 0 14px; } .rp-shell.rail .brand-text, .rp-shell.rail .nav-item > span, .rp-shell.rail .nav-group .chev, .rp-shell.rail .nav-sub, .rp-shell.rail .me > div, .rp-shell.rail .me > .icon { display: none; } .rp-shell.rail .nav { padding: 6px 12px 14px; } .rp-shell.rail .nav-label { padding: 0; height: 21px; position: relative; } .rp-shell.rail .nav-label > * { display: none; } .rp-shell.rail .nav-label::after { content: ''; position: absolute; left: 12px; right: 12px; top: 10px; height: 1px; background: var(--line-2); } .rp-shell.rail .nav-item { justify-content: center; padding: 0; height: 42px; } .rp-shell.rail .nav-badge { position: absolute; top: 4px; right: 4px; min-width: 16px; height: 16px; padding: 0 4px; font-size: 10px; margin: 0; box-shadow: 0 0 0 2px var(--paper-2); } .rp-shell.rail .sidebar-foot { padding: 12px; } .rp-shell.rail .me { justify-content: center; padding: 6px 0; } @media (max-width: 1100px) { .page-head { flex-direction: column; align-items: flex-start; gap: 20px; } .page-head .actions { flex-wrap: wrap; } .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } .stat:nth-child(odd)::before { display: none; } .stat:nth-child(n + 3) { border-top: 1px solid var(--line); } } @media (max-width: 900px) { .rp-shell .topbar { padding: 0 18px; gap: 8px; } .title { font-size: 30px; } } @media (max-width: 640px) { .stats { grid-template-columns: 1fr; } .stat::before { display: none !important; } .stat + .stat { border-top: 1px solid var(--line); } .stat-value { font-size: 36px; } }