leethobbit_obsidian-strong-.../styles.css
Dan 9da7a5ea11 Address store review CSS lint: drop :has() and !important [skip changelog]
The scene row gains a has-detail class where the chevron is created,
replacing the :has() selector (broad invalidation). The reduced-motion
override now names .is-nat1 explicitly and relies on source order
instead of !important. Rendered behavior is identical.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 16:32:00 -04:00

3178 lines
67 KiB
CSS

/* All plugin CSS lives here, prefixed .strong-start- so it never collides.
Use Obsidian CSS variables (var(--text-normal), var(--background-secondary),
var(--interactive-accent), ...) — never hardcoded colors or inline styles,
so themes and snippets can restyle the plugin. */
/* Icons inside any plugin element must never flex-squeeze: Obsidian's default
button padding plus a fixed button width can otherwise collapse the icon
SVG to zero width (it renders "blank" while the tooltip still works). */
[class*="strong-start"] .svg-icon {
flex-shrink: 0;
}
/* ---- View shell -------------------------------------------------------- */
.strong-start-view {
display: flex;
flex-direction: row;
height: 100%;
color: var(--text-normal);
}
.strong-start-main {
display: flex;
flex-direction: column;
flex: 1 1 auto;
min-width: 0;
height: 100%;
}
/* ---- Icon rail ----------------------------------------------------------
Phone bottom-bar collapse is a later milestone (M1 just ensures nothing
breaks at narrow widths — the rail stays a rail). */
.strong-start-rail {
display: flex;
flex-direction: column;
flex: 0 0 auto;
width: 11rem;
padding: var(--size-4-2);
background-color: var(--background-secondary);
border-right: 1px solid var(--background-modifier-border);
}
.strong-start-rail-group {
display: flex;
flex-direction: column;
align-items: stretch;
gap: var(--size-4-1);
padding-bottom: var(--size-4-2);
margin-bottom: var(--size-4-2);
border-bottom: 1px solid var(--background-modifier-border);
}
.strong-start-rail-group:last-of-type {
border-bottom: none;
}
.strong-start-rail-footer {
display: flex;
flex-direction: column;
align-items: stretch;
margin-top: auto;
padding-top: var(--size-4-2);
border-top: 1px solid var(--background-modifier-border);
}
.strong-start-rail-button {
display: flex;
align-items: center;
justify-content: flex-start;
gap: var(--size-4-2);
width: 100%;
height: var(--size-4-9);
padding: 0 var(--size-4-3);
margin: var(--size-4-1) 0;
color: var(--text-muted);
background: transparent;
border: none;
border-radius: var(--radius-m);
box-shadow: none;
cursor: var(--cursor-link);
text-align: left;
}
.strong-start-rail-icon {
display: flex;
align-items: center;
justify-content: center;
flex: 0 0 auto;
}
.strong-start-rail-label {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: var(--font-ui-small);
}
.strong-start-rail-button:hover {
color: var(--text-normal);
background-color: var(--background-modifier-hover);
}
.strong-start-rail-button.is-active {
color: var(--text-on-accent);
background-color: var(--interactive-accent);
}
.strong-start-rail-button.is-active:hover {
background-color: var(--interactive-accent-hover);
}
/* ---- Header (persistent, outside the swapped body) ---------------------- */
.strong-start-header {
display: flex;
align-items: center;
justify-content: space-between;
flex: 0 0 auto;
gap: var(--size-4-2);
padding: var(--size-4-2) var(--size-4-4);
border-bottom: 1px solid var(--background-modifier-border);
}
.strong-start-header-selector select {
font-weight: var(--font-medium);
}
.strong-start-header-menu {
display: flex;
align-items: center;
justify-content: center;
padding: var(--size-4-1) var(--size-4-2);
color: var(--text-muted);
background: transparent;
border: none;
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-header-menu:hover {
color: var(--text-normal);
}
/* ---- Body / panels ------------------------------------------------------ */
.strong-start-body {
flex: 1 1 auto;
overflow-y: auto;
padding: var(--size-4-4);
}
.strong-start-panel {
display: flex;
flex-direction: column;
gap: var(--size-4-4);
height: 100%;
}
/* ---- Dashboard cards ------------------------------------------------------ */
.strong-start-card {
padding: var(--size-4-4);
background-color: var(--background-secondary);
border-radius: var(--radius-m);
}
.strong-start-card h3 {
margin-top: 0;
}
.strong-start-card-action {
display: flex;
gap: var(--size-4-2);
}
.strong-start-session-list {
margin: 0;
padding-left: var(--size-4-4);
}
.strong-start-session-link {
cursor: var(--cursor-link);
}
/* ---- Empty states --------------------------------------------------------- */
.strong-start-empty-state {
color: var(--text-muted);
font-style: italic;
}
.strong-start-empty-state-action {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--size-4-2);
max-width: 32em;
margin: var(--size-4-8) auto;
padding: var(--size-4-6);
text-align: center;
background-color: var(--background-secondary);
border-radius: var(--radius-m);
}
.strong-start-empty-state-title {
margin: 0;
font-size: var(--font-ui-large);
font-weight: var(--font-semibold);
}
.strong-start-empty-state-body {
margin: 0;
color: var(--text-muted);
}
.strong-start-empty-state-buttons {
display: flex;
gap: var(--size-4-2);
}
/* ---- Dashboard progress dots ----------------------------------------------- */
.strong-start-progress-dots {
display: flex;
gap: var(--size-4-1);
margin: var(--size-4-2) 0;
}
.strong-start-progress-dot {
width: var(--size-4-2);
height: var(--size-4-2);
background-color: var(--background-modifier-border);
border-radius: var(--radius-full);
}
.strong-start-progress-dot.is-done {
background-color: var(--interactive-accent);
}
/* ---- Dashboard: Secrets in play card ---------------------------------------- */
.strong-start-secrets-card-heading {
display: flex;
align-items: center;
gap: var(--size-4-1);
margin-top: 0;
}
.strong-start-secrets-card-stale {
display: flex;
align-items: center;
color: var(--text-warning, var(--color-orange));
}
.strong-start-secrets-card-list {
margin: 0 0 var(--size-4-2);
padding-left: var(--size-4-4);
}
.strong-start-secrets-card-item {
color: var(--text-muted);
}
.strong-start-secrets-card-link {
cursor: var(--cursor-link);
}
/* ---- Prep board ------------------------------------------------------------ */
.strong-start-prep-shell {
display: flex;
flex-direction: column;
gap: var(--size-4-4);
height: 100%;
}
.strong-start-prep-toolbar {
display: flex;
align-items: center;
flex: 0 0 auto;
gap: var(--size-4-2);
}
.strong-start-prep-progress {
margin-left: auto;
color: var(--text-muted);
}
/* container-type lives on the SHELL (the board's parent) — an @container rule
can only restyle elements INSIDE the container, so putting it on the board
itself silently skipped the board's own narrow-layout direction switch. */
.strong-start-prep-shell {
container-type: inline-size;
}
.strong-start-prep-board {
display: flex;
flex: 1 1 auto;
gap: var(--size-4-4);
min-height: 0;
}
.strong-start-prep-master {
display: flex;
flex: 0 0 auto;
flex-direction: column;
width: 14rem;
overflow-y: auto;
border-right: 1px solid var(--background-modifier-border);
}
.strong-start-prep-workspace {
flex: 1 1 auto;
min-width: 0;
overflow-y: auto;
padding-left: var(--size-4-4);
}
.strong-start-step-row {
display: flex;
align-items: center;
gap: var(--size-4-2);
padding: var(--size-4-2);
cursor: var(--cursor-link);
border-radius: var(--radius-m);
}
.strong-start-step-row:hover {
background-color: var(--background-modifier-hover);
}
.strong-start-step-row.is-active {
background-color: var(--background-modifier-active-hover);
}
.strong-start-step-circle {
display: flex;
align-items: center;
justify-content: center;
width: var(--size-4-6);
height: var(--size-4-6);
flex: 0 0 auto;
color: var(--text-muted);
background: transparent;
border: none;
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-step-circle.is-done {
color: var(--text-success);
}
.strong-start-step-circle.is-auto {
color: var(--text-accent);
}
.strong-start-step-number {
color: var(--text-faint);
font-size: var(--font-ui-smaller);
}
.strong-start-step-label {
flex: 1 1 auto;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.strong-start-step-summary {
color: var(--text-muted);
font-size: var(--font-ui-smaller);
}
/* Master list collapses to a horizontal scrollable strip in a narrow panel
* (the full phone shell is a later milestone — this just keeps M2 from
* breaking narrow). */
@container (max-width: 700px) {
.strong-start-prep-board {
flex-direction: column;
}
.strong-start-prep-master {
flex-direction: row;
width: 100%;
overflow-x: auto;
overflow-y: visible;
border-right: none;
border-bottom: 1px solid var(--background-modifier-border);
}
.strong-start-step-row {
flex: 0 0 auto;
}
.strong-start-step-label {
white-space: nowrap;
}
.strong-start-prep-workspace {
padding-left: 0;
}
}
.strong-start-hint {
color: var(--text-muted);
font-size: var(--font-ui-smaller);
}
.strong-start-strong-start-textarea {
width: 100%;
resize: vertical;
}
.strong-start-malformed-banner {
display: flex;
align-items: center;
gap: var(--size-4-2);
padding: var(--size-4-2);
background-color: var(--background-modifier-error-hover);
border-radius: var(--radius-m);
}
/* ---- List rows (Scenes/Rewards) --------------------------------------------- */
.strong-start-list-rows {
display: flex;
flex-direction: column;
gap: var(--size-4-1);
}
.strong-start-list-row {
display: flex;
align-items: center;
gap: var(--size-4-2);
}
.strong-start-list-row-input {
flex: 1 1 auto;
}
.strong-start-list-row-detail-toggle.has-detail {
color: var(--text-accent);
}
.strong-start-list-row-detail {
width: calc(100% - var(--size-4-6));
margin: var(--size-2-2) 0 var(--size-4-2) var(--size-4-6);
resize: vertical;
}
.strong-start-list-row-controls {
display: flex;
flex: 0 0 auto;
gap: var(--size-4-1);
}
.strong-start-icon-button {
display: flex;
align-items: center;
justify-content: center;
width: var(--size-4-6);
height: var(--size-4-6);
padding: 0;
color: var(--text-muted);
background: transparent;
border: none;
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-icon-button:hover {
color: var(--text-normal);
}
/* ---- Secrets step ----------------------------------------------------------- */
.strong-start-progress-text {
color: var(--text-muted);
}
.strong-start-secret-section-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--size-4-2);
margin-top: var(--size-4-3);
}
.strong-start-secret-section-heading {
margin: 0;
color: var(--text-muted);
font-size: var(--font-ui-small);
}
.strong-start-secret-sync-button,
.strong-start-secret-retired-toggle {
display: flex;
align-items: center;
gap: var(--size-4-1);
color: var(--text-muted);
font-size: var(--font-ui-smaller);
background: transparent;
border: none;
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-secret-sync-button:hover,
.strong-start-secret-retired-toggle:hover {
color: var(--text-normal);
}
.strong-start-secret-rows {
display: flex;
flex-direction: column;
gap: var(--size-4-1);
margin-bottom: var(--size-4-2);
}
.strong-start-secret-row {
display: flex;
align-items: center;
gap: var(--size-4-2);
padding: var(--size-4-1) var(--size-4-2);
border-radius: var(--radius-m);
}
.strong-start-secret-row.is-retired {
opacity: 0.6;
}
.strong-start-secret-input,
.strong-start-secret-add-input,
.strong-start-secret-retired-text {
flex: 1 1 auto;
}
.strong-start-secret-hourglass {
display: flex;
flex: 0 0 auto;
color: var(--text-muted);
}
.strong-start-secret-origin-tag {
flex: 0 0 auto;
color: var(--text-faint);
font-size: var(--font-ui-smaller);
}
.strong-start-secret-action-button {
flex: 0 0 auto;
color: var(--text-muted);
font-size: var(--font-ui-smaller);
}
/* Aged tint on carried secrets — subtle warm wash that deepens with how many
* sessions a secret has ridden along unrevealed (docs/plan.md delight detail:
* "aged-secret warm tint + hourglass"). `carried-N` = N sessions past origin. */
.strong-start-secret-row.is-carried-1 {
background-color: color-mix(in srgb, var(--color-orange) 6%, transparent);
}
.strong-start-secret-row.is-carried-2 {
background-color: color-mix(in srgb, var(--color-orange) 12%, transparent);
}
.strong-start-secret-row.is-carried-3-plus {
background-color: color-mix(in srgb, var(--color-orange) 20%, transparent);
border-left: 2px solid var(--color-orange);
}
.strong-start-secret-retired-toggle-row {
margin-top: var(--size-4-3);
}
.strong-start-secret-retired-list.is-hidden {
display: none;
}
/* ---- Chip editor (Locations/NPCs/Monsters) ---------------------------------- */
.strong-start-chip-row {
display: flex;
flex-wrap: wrap;
gap: var(--size-4-2);
margin-bottom: var(--size-4-2);
}
.strong-start-chip {
display: flex;
align-items: center;
gap: var(--size-4-1);
padding: var(--size-4-1) var(--size-4-2);
background-color: var(--background-secondary);
border-radius: var(--radius-l);
}
.strong-start-chip-label.is-linked {
color: var(--link-color);
cursor: var(--cursor-link);
}
.strong-start-chip-create {
font-size: var(--font-ui-smaller);
}
.strong-start-chip-input-row {
display: flex;
}
.strong-start-chip-input {
width: 100%;
}
/* ---- Roster (Characters step) ----------------------------------------------- */
.strong-start-roster-list {
margin: 0 0 var(--size-4-2);
padding-left: var(--size-4-4);
}
/* ---- Form modal (create campaign, etc.) ----------------------------------- */
.strong-start-form-modal-buttons {
display: flex;
justify-content: flex-end;
gap: var(--size-4-2);
margin-top: var(--size-4-4);
}
/* ---- Inspire control + roll chip (uniform inspiration-roll pattern) -------- */
.strong-start-inspire {
display: flex;
flex-direction: column;
gap: var(--size-4-2);
margin-top: var(--size-4-3);
}
.strong-start-inspire-header {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--size-4-2);
}
.strong-start-inspire-pills {
display: flex;
flex-wrap: wrap;
gap: var(--size-4-1);
}
.strong-start-inspire-pill {
padding: var(--size-4-1) var(--size-4-2);
color: var(--text-muted);
font-size: var(--font-ui-smaller);
background-color: var(--background-secondary);
border: none;
border-radius: var(--radius-l);
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-inspire-pill.is-active {
color: var(--text-on-accent);
background-color: var(--interactive-accent);
}
.strong-start-inspire-button {
display: flex;
align-items: center;
justify-content: center;
}
.strong-start-roll-chip {
display: flex;
flex-direction: column;
gap: var(--size-4-1);
max-width: 32em;
padding: var(--size-4-2) var(--size-4-3);
background-color: var(--background-secondary);
border-left: 2px solid var(--interactive-accent);
border-radius: var(--radius-m);
}
.strong-start-roll-chip-text {
color: var(--text-normal);
white-space: pre-wrap;
}
.strong-start-roll-chip-source {
color: var(--text-faint);
font-size: var(--font-ui-smaller);
}
.strong-start-roll-chip-buttons {
display: flex;
align-items: center;
gap: var(--size-4-2);
margin-top: var(--size-4-1);
}
/* ---- Tables panel ------------------------------------------------------------ */
.strong-start-tables-shell {
display: flex;
flex-direction: column;
gap: var(--size-4-3);
height: 100%;
}
/* Same shell-owns-the-container rule as the prep board: an @container query
cannot restyle the container element itself. */
.strong-start-tables-shell {
container-type: inline-size;
}
.strong-start-tables-board {
display: flex;
flex: 1 1 auto;
gap: var(--size-4-4);
min-height: 0;
}
.strong-start-tables-list {
display: flex;
flex: 0 0 auto;
flex-direction: column;
width: 16rem;
overflow-y: auto;
border-right: 1px solid var(--background-modifier-border);
}
.strong-start-tables-category {
margin: var(--size-4-3) 0 var(--size-4-1);
color: var(--text-faint);
font-size: var(--font-ui-smaller);
text-transform: uppercase;
}
.strong-start-tables-category:first-child {
margin-top: 0;
}
/* Row selectors are scoped under the list because Obsidian's own
`button:not(.clickable-icon)` (0-1-1) outranks a lone class (0-1-0) — unscoped,
the rows render as the app's centered nowrap pills and long names clip. */
.strong-start-tables-list .strong-start-tables-row {
flex: 0 0 auto;
justify-content: flex-start; /* the app's button rule is a centering flexbox */
height: auto;
padding: var(--size-4-1) var(--size-4-2);
overflow-wrap: anywhere;
text-align: left;
white-space: normal;
color: var(--text-normal);
background: transparent;
border: none;
border-radius: var(--radius-m);
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-tables-list .strong-start-tables-row:hover {
background-color: var(--background-modifier-hover);
}
.strong-start-tables-list .strong-start-tables-row.is-active {
background-color: var(--background-modifier-active-hover);
}
.strong-start-tables-detail {
flex: 1 1 auto;
min-width: 0;
overflow-y: auto;
padding-left: var(--size-4-4);
}
.strong-start-tables-roll-button {
margin: var(--size-4-2) 0 var(--size-4-3);
}
.strong-start-tables-result-stack {
display: flex;
flex-direction: column;
gap: var(--size-4-2);
}
.strong-start-tables-result-card {
padding: var(--size-4-2) var(--size-4-3);
background-color: var(--background-secondary);
border-radius: var(--radius-m);
}
.strong-start-tables-result-text {
white-space: pre-wrap;
}
.strong-start-tables-result-buttons {
display: flex;
gap: var(--size-4-2);
margin-top: var(--size-4-1);
}
.strong-start-tables-trace {
margin-top: var(--size-4-1);
color: var(--text-muted);
font-size: var(--font-ui-smaller);
}
.strong-start-tables-trace ul {
margin: var(--size-4-1) 0 0;
padding-left: var(--size-4-4);
}
.strong-start-tables-footer {
flex: 0 0 auto;
color: var(--text-faint);
font-size: var(--font-ui-smaller);
}
/* ---- Tables panel: shadowed core rows ("hidden — replaced by your table") --- */
.strong-start-tables-list .strong-start-tables-row-shadowed {
display: flex;
flex-wrap: wrap;
color: var(--text-faint);
}
.strong-start-tables-shadowed-label {
color: var(--text-faint);
font-size: var(--font-ui-smaller);
font-style: italic;
}
.strong-start-tables-shadow-banner {
padding: var(--size-4-2) var(--size-4-3);
margin-bottom: var(--size-4-2);
color: var(--text-muted);
font-size: var(--font-ui-smaller);
background-color: var(--background-secondary);
border-left: 2px solid var(--text-faint);
border-radius: var(--radius-m);
}
.strong-start-tables-peek-list {
margin: 0;
padding-left: var(--size-4-4);
color: var(--text-muted);
}
/* ---- Tables panel: My tables (M5 custom tables) ----------------------------- */
.strong-start-tables-mytables-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--size-4-2);
margin: var(--size-4-3) 0 var(--size-4-1);
}
.strong-start-tables-mytables-header .strong-start-tables-category {
margin: 0;
}
.strong-start-tables-new-button {
padding: var(--size-4-1) var(--size-4-2);
font-size: var(--font-ui-smaller);
}
.strong-start-tables-user-row {
display: flex;
align-items: center;
gap: var(--size-4-1);
padding: var(--size-4-1) var(--size-4-2);
border-radius: var(--radius-m);
}
.strong-start-tables-user-row:hover {
background-color: var(--background-modifier-hover);
}
.strong-start-tables-user-row.is-active {
background-color: var(--background-modifier-active-hover);
}
/* Scoped for the same specificity reason as .strong-start-tables-row above. */
.strong-start-tables-user-row .strong-start-tables-row-name {
flex: 1 1 auto;
justify-content: flex-start; /* the app's button rule is a centering flexbox */
height: auto;
min-width: 0;
padding: 0;
overflow-wrap: anywhere;
text-align: left;
white-space: normal;
color: var(--text-normal);
background: transparent;
border: none;
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-tables-badge {
flex: 0 0 auto;
padding: 0 var(--size-4-1);
color: var(--text-muted);
font-size: var(--font-ui-smaller);
background-color: var(--background-modifier-border);
border-radius: var(--radius-s);
}
.strong-start-tables-user-row-actions {
display: flex;
flex: 0 0 auto;
gap: var(--size-4-1);
}
/* ---- Table editor modal (create/edit a custom table, M5) -------------------- */
.strong-start-table-editor-textarea-wrap {
margin-top: var(--size-4-2);
}
.strong-start-table-editor-textarea {
width: 100%;
resize: vertical;
}
.strong-start-table-editor-footer {
margin-top: var(--size-4-1);
}
.strong-start-table-editor-preview-row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--size-4-2);
margin-top: var(--size-4-3);
}
.strong-start-table-editor-preview-result {
color: var(--text-normal);
}
/* Two-pane collapses to a single column in a narrow phone-emulation panel. */
@container (max-width: 700px) {
.strong-start-tables-board {
flex-direction: column;
}
.strong-start-tables-list {
width: 100%;
border-right: none;
border-bottom: 1px solid var(--background-modifier-border);
}
.strong-start-tables-detail {
padding-left: 0;
}
}
/* ---- Tables panel: Roll / Generators sub-tabs (M7) -------------------------- */
.strong-start-tables-subtabs {
display: flex;
flex: 0 0 auto;
gap: var(--size-4-2);
margin-bottom: var(--size-4-1);
border-bottom: 1px solid var(--background-modifier-border);
}
.strong-start-tables-subtab {
padding: var(--size-4-1) var(--size-4-2);
color: var(--text-muted);
background: transparent;
border: none;
border-bottom: 2px solid transparent;
border-radius: 0;
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-tables-subtab.is-active {
color: var(--text-normal);
border-bottom-color: var(--interactive-accent);
}
/* ---- Generators sub-tab (M7) ------------------------------------------------ */
.strong-start-generators-shell {
display: flex;
flex-direction: column;
gap: var(--size-4-3);
height: 100%;
overflow-y: auto;
}
.strong-start-generators-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
gap: var(--size-4-3);
}
.strong-start-generator-card {
display: flex;
flex-direction: column;
gap: var(--size-4-2);
padding: var(--size-4-3);
background-color: var(--background-secondary);
border-radius: var(--radius-m);
}
.strong-start-generator-card-header {
display: flex;
align-items: center;
gap: var(--size-4-2);
}
.strong-start-generator-card-icon {
display: flex;
color: var(--text-muted);
}
.strong-start-generator-card-label {
flex: 1 1 auto;
font-weight: var(--font-weight-medium);
}
.strong-start-generator-card-result h4 {
margin: 0 0 var(--size-4-2);
}
.strong-start-generator-lines {
display: flex;
flex-direction: column;
gap: var(--size-4-1);
}
.strong-start-generator-line {
display: flex;
align-items: baseline;
gap: var(--size-4-1);
}
.strong-start-generator-line-label {
flex: 0 0 auto;
color: var(--text-muted);
}
.strong-start-generator-line-text {
flex: 1 1 auto;
/* `min-width: 0` is the fix — without it a flex item's default min-width
(auto) keeps it at its max-content (single-line) width, so a long
generated line pushes the card wider instead of wrapping. */
min-width: 0;
white-space: normal;
overflow-wrap: break-word;
}
.strong-start-generator-actions {
display: flex;
flex-wrap: wrap;
gap: var(--size-4-2);
margin-top: var(--size-4-1);
}
/* ---- NPCs step: "Generate NPC" preview card (M7) ---------------------------- */
.strong-start-npc-preview {
display: flex;
flex-direction: column;
gap: var(--size-4-2);
max-width: 32em;
padding: var(--size-4-2) var(--size-4-3);
margin-top: var(--size-4-2);
background-color: var(--background-secondary);
border-left: 2px solid var(--interactive-accent);
border-radius: var(--radius-m);
}
.strong-start-npc-preview-lines {
display: flex;
flex-direction: column;
gap: var(--size-4-1);
}
.strong-start-npc-preview-line {
display: flex;
gap: var(--size-4-1);
}
.strong-start-npc-preview-label {
color: var(--text-muted);
}
/* ---- Secrets ledger ---------------------------------------------------------- */
.strong-start-secrets-shell {
display: flex;
flex-direction: column;
gap: var(--size-4-3);
}
.strong-start-secrets-stat-line {
color: var(--text-muted);
}
.strong-start-secrets-filters {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--size-4-2);
}
.strong-start-secrets-chips {
display: flex;
flex-wrap: wrap;
gap: var(--size-4-1);
}
.strong-start-secrets-chip {
padding: var(--size-4-1) var(--size-4-2);
color: var(--text-muted);
font-size: var(--font-ui-smaller);
background-color: var(--background-secondary);
border: none;
border-radius: var(--radius-l);
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-secrets-chip.is-active {
color: var(--text-on-accent);
background-color: var(--interactive-accent);
}
.strong-start-secrets-filter-text {
flex: 1 1 auto;
min-width: 10rem;
margin-left: auto;
}
.strong-start-secrets-list {
display: flex;
flex-direction: column;
gap: var(--size-4-4);
}
.strong-start-secrets-group-heading {
margin: 0 0 var(--size-4-1);
color: var(--text-faint);
font-size: var(--font-ui-smaller);
text-transform: uppercase;
}
.strong-start-secrets-row {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: var(--size-4-3);
padding: var(--size-4-2) var(--size-4-3);
margin-bottom: var(--size-4-1);
background-color: var(--background-secondary);
border-radius: var(--radius-m);
}
.strong-start-secrets-row.is-retired {
opacity: 0.6;
}
/* Same aged-tint scale as the prep board's carried strip. */
.strong-start-secrets-row.is-carried-1 {
background-color: color-mix(in srgb, var(--color-orange) 6%, var(--background-secondary));
}
.strong-start-secrets-row.is-carried-2 {
background-color: color-mix(in srgb, var(--color-orange) 12%, var(--background-secondary));
}
.strong-start-secrets-row.is-carried-3-plus {
background-color: color-mix(in srgb, var(--color-orange) 20%, var(--background-secondary));
border-left: 2px solid var(--color-orange);
}
.strong-start-secrets-row-main {
display: flex;
flex-direction: column;
gap: var(--size-4-1);
min-width: 0;
}
.strong-start-secrets-row-text {
color: var(--text-normal);
}
.strong-start-secrets-row-meta {
display: flex;
align-items: center;
gap: var(--size-4-2);
color: var(--text-faint);
font-size: var(--font-ui-smaller);
}
.strong-start-secrets-badge {
padding: 0 var(--size-4-1);
background-color: var(--background-modifier-border);
border-radius: var(--radius-s);
}
.strong-start-secrets-row-note {
color: var(--text-muted);
font-size: var(--font-ui-smaller);
font-style: italic;
}
.strong-start-secrets-row-actions {
display: flex;
flex: 0 0 auto;
align-items: center;
gap: var(--size-4-1);
}
/* ---- Collapsible sections (panel-kit.ts SectionState) ----------------------- */
.strong-start-collapsible-header {
display: flex;
align-items: center;
gap: var(--size-4-1);
width: 100%;
min-height: 44px;
padding: var(--size-4-1) 0;
color: var(--text-muted);
font-variant: small-caps;
text-transform: lowercase;
background: transparent;
border: none;
box-shadow: none;
cursor: var(--cursor-link);
}
/* Small-caps reads a couple of sizes smaller than it measures — bump the
label so section headers hold their own against body text (run UI pass,
2026-07-14). Shared by every collapsible: run sections, glance sidebar,
World groups, session zero, the 5e drawer. */
.strong-start-collapsible-label {
/* rem, not em — the run pane inherits a 13px base that em can't escape. */
font-size: 1.1rem;
}
.strong-start-collapsible-chevron {
display: flex;
align-items: center;
}
.strong-start-collapsible-body.is-hidden {
display: none;
}
/* ---- Run mode ---------------------------------------------------------------
docs/plan.md: read-optimized, big type, one-tap-or-nothing, cannot be
accidentally edited — the log bar is the only writing surface. */
.strong-start-run-shell {
--lazy-run-font: 18px;
position: relative;
display: flex;
flex-direction: column;
height: 100%;
font-size: var(--lazy-run-font);
line-height: 1.6;
}
.strong-start-run-shell.is-text-sm {
--lazy-run-font: 16px;
}
.strong-start-run-shell.is-text-md {
--lazy-run-font: 18px;
}
.strong-start-run-shell.is-text-lg {
--lazy-run-font: 22px;
}
.strong-start-run-topbar {
display: flex;
flex: 0 0 auto;
align-items: center;
gap: var(--size-4-2);
padding-bottom: var(--size-4-2);
border-bottom: 1px solid var(--background-modifier-border);
}
.strong-start-run-session-label {
font-weight: var(--font-semibold);
white-space: nowrap;
}
.strong-start-run-timer {
color: var(--text-muted);
font-variant-numeric: tabular-nums;
}
.strong-start-run-end-button {
margin-left: auto;
}
.strong-start-run-icon-button {
display: flex;
align-items: center;
justify-content: center;
min-width: 44px;
min-height: 44px;
color: var(--text-muted);
background: transparent;
border: none;
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-run-icon-button:hover {
color: var(--text-normal);
}
.strong-start-run-popover-anchor {
position: relative;
display: flex;
align-items: center;
}
.strong-start-run-popover {
position: absolute;
top: 100%;
right: 0;
z-index: 6;
min-width: 12rem;
margin-top: var(--size-4-1);
padding: var(--size-4-2);
background-color: var(--background-secondary);
border: 1px solid var(--background-modifier-border);
border-radius: var(--radius-m);
box-shadow: var(--shadow-s);
}
.strong-start-run-dice-popover {
display: flex;
flex-direction: column;
gap: var(--size-4-2);
min-width: 16rem;
}
.strong-start-run-dice-config-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--size-4-2);
min-height: 44px;
}
.strong-start-run-dice-config-label {
color: var(--text-muted);
font-size: var(--font-ui-small);
}
.strong-start-run-dice-die-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: var(--size-4-1);
}
.strong-start-run-dice-die {
min-height: 44px;
}
.strong-start-run-dice-die.is-selected {
background-color: var(--interactive-accent);
color: var(--text-on-accent);
}
.strong-start-run-dice-roll {
width: 100%;
min-height: 44px;
}
.strong-start-run-dice-advrow {
display: flex;
gap: var(--size-4-1);
}
.strong-start-run-dice-advrow button {
flex: 1 1 0;
min-height: 44px;
}
.strong-start-run-textsize-row {
display: flex;
align-items: center;
gap: var(--size-4-2);
}
/* Container on the shell, not the board — see the prep-board comment. */
.strong-start-run-shell {
container-type: inline-size;
}
.strong-start-run-board {
display: flex;
flex: 1 1 auto;
gap: var(--size-4-5);
min-height: 0;
padding-top: var(--size-4-3);
overflow-y: auto;
}
.strong-start-run-main {
display: flex;
flex: 1 1 auto;
flex-direction: column;
gap: var(--size-4-5);
min-width: 0;
}
.strong-start-run-glance {
display: flex;
flex: 0 0 auto;
flex-direction: column;
width: 18rem;
gap: var(--size-4-2);
}
/* The focus pane earns a wider column — 18rem list chrome is too narrow for
rendered note prose. */
.strong-start-run-glance.is-detail {
width: 24rem;
}
@container (max-width: 700px) {
.strong-start-run-board {
flex-direction: column;
}
/* Side-by-side Scenes/Secrets columns don't fit a narrow pane. */
.strong-start-run-sections-row {
flex-direction: column;
align-items: stretch;
}
.strong-start-run-glance,
.strong-start-run-glance.is-detail {
width: 100%;
}
/* Narrow pane (not just phones): let the top bar wrap instead of clipping
the End button behind a horizontal scrollbar. */
.strong-start-run-topbar {
flex-wrap: wrap;
}
}
.strong-start-run-section-label {
margin-bottom: var(--size-4-1);
color: var(--text-muted);
font-variant: small-caps;
font-size: 0.8em;
text-transform: lowercase;
}
.strong-start-run-strong-start-body {
font-size: 1.25em;
}
/* Scenes/Secrets sit side by side at full width (run UI pass, 2026-07-14) —
equal columns, collapsing back to a stack when the pane gets narrow. */
.strong-start-run-sections-row {
display: flex;
gap: var(--size-4-2);
align-items: flex-start;
}
.strong-start-run-sections-row > .strong-start-run-section {
flex: 1 1 0;
min-width: 0;
}
.strong-start-run-scene-list,
.strong-start-run-secret-list {
display: flex;
flex-direction: column;
gap: var(--size-4-1);
}
/* The row owns the pill (background + radius); the toggle fills it and the
detail chevron is OVERLAID on the pill's right edge (absolute, full pill
height, no chrome of its own) so it can never read as a separate segment
(run UI pass, 2026-07-14). */
.strong-start-run-scene-row {
position: relative;
display: flex;
align-items: stretch;
background-color: var(--background-secondary);
border-radius: var(--radius-m);
}
.strong-start-run-scene-toggle {
display: flex;
flex: 1 1 auto;
align-items: center;
gap: var(--size-4-2);
min-height: 44px;
padding: var(--size-4-1) var(--size-4-2);
color: var(--text-normal);
text-align: left;
background-color: transparent;
border: none;
border-radius: var(--radius-m);
box-shadow: none;
cursor: var(--cursor-link);
}
/* Keep the scene text clear of the overlaid chevron. `has-detail` is set by
the panel when it creates the chevron (a :has() here trips the store lint). */
.strong-start-run-scene-row.has-detail .strong-start-run-scene-toggle {
padding-right: 48px;
}
.strong-start-run-scene-expand {
position: absolute;
top: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
width: 44px;
height: 100%;
padding: 0;
color: var(--text-muted);
background: transparent;
background-color: transparent;
border: none;
border-radius: 0 var(--radius-m) var(--radius-m) 0;
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-run-scene-expand:hover {
color: var(--text-normal);
background-color: var(--background-modifier-hover);
}
.strong-start-run-scene-detail {
margin: 0 0 var(--size-4-1) var(--size-4-6);
}
.strong-start-run-scene-detail > :first-child {
margin-top: 0;
}
.strong-start-run-scene-detail > :last-child {
margin-bottom: 0;
}
.strong-start-run-scene-check {
display: flex;
flex: 0 0 auto;
color: var(--text-accent);
}
.strong-start-run-scene-row.is-done {
opacity: 0.6;
}
.strong-start-run-scene-row.is-done .strong-start-run-scene-text {
text-decoration: line-through;
}
.strong-start-run-scene-row.is-done .strong-start-run-scene-check {
color: var(--text-success);
}
.strong-start-run-secret-card {
position: relative;
display: flex;
flex-direction: column;
gap: var(--size-4-2);
min-height: 44px;
padding: var(--size-4-1) var(--size-4-2);
background-color: var(--background-secondary);
border-radius: var(--radius-m);
cursor: var(--cursor-link);
}
/* Persistent re-hide on revealed cards — same overlaid-icon treatment as the
scene-detail chevron. Text keeps clear of it via the padding below. */
.strong-start-run-secret-card.is-revealed {
padding-right: 48px;
}
.strong-start-run-secret-hide {
position: absolute;
top: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
width: 44px;
height: 100%;
padding: 0;
color: var(--text-muted);
background-color: transparent;
border: none;
border-radius: 0 var(--radius-m) var(--radius-m) 0;
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-run-secret-hide:hover {
color: var(--text-normal);
background-color: var(--background-modifier-hover);
}
/* Hidden and revealed secrets are compact one-line rows; only the peeked
state expands into a column (text + Mark revealed). */
.strong-start-run-secret-card.is-hidden,
.strong-start-run-secret-card.is-revealed {
flex-direction: row;
align-items: center;
}
.strong-start-run-secret-card.is-revealed .strong-start-run-secret-text {
flex: 1 1 auto;
}
.strong-start-run-secret-card.is-revealed {
cursor: default;
border-left: 2px solid var(--text-success);
}
.strong-start-run-secret-card.is-peeked {
border-left: 2px solid var(--interactive-accent);
}
.strong-start-run-secret-icon {
display: flex;
color: var(--text-muted);
}
.strong-start-run-secret-text {
color: var(--text-normal);
white-space: pre-wrap;
}
.strong-start-run-secret-mask {
display: flex;
flex: 1 1 auto;
}
.strong-start-run-secret-mask-bar {
width: 100%;
height: 0.8em;
background: repeating-linear-gradient(
135deg,
var(--background-modifier-border) 0,
var(--background-modifier-border) 6px,
var(--background-secondary) 6px,
var(--background-secondary) 12px
);
border-radius: var(--radius-s);
}
.strong-start-run-secret-mark,
.strong-start-run-secret-undo {
align-self: flex-start;
min-height: 44px;
}
.strong-start-run-glance-list {
margin: 0;
padding-left: var(--size-4-4);
}
.strong-start-run-glance-item {
color: var(--text-normal);
}
.strong-start-run-glance-link {
cursor: var(--cursor-link);
}
.strong-start-run-glance-role {
color: var(--text-muted);
}
.strong-start-run-entity-header {
display: flex;
align-items: center;
gap: var(--size-4-1);
min-height: 44px;
}
.strong-start-run-entity-title {
flex: 1 1 auto;
min-width: 0;
overflow: hidden;
font-weight: var(--font-bold);
text-overflow: ellipsis;
white-space: nowrap;
}
.strong-start-run-entity-fields {
display: grid;
grid-template-columns: auto 1fr;
gap: var(--size-2-2) var(--size-4-3);
margin: var(--size-4-2) 0;
}
.strong-start-run-entity-field-label {
color: var(--text-muted);
font-size: var(--font-ui-small);
text-transform: uppercase;
letter-spacing: 0.04em;
}
.strong-start-run-entity-body {
overflow-y: auto;
min-height: 0;
}
.strong-start-run-overlay {
position: absolute;
inset: 0;
z-index: 10;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--background-primary);
cursor: var(--cursor-link);
}
.strong-start-run-safety-card {
max-width: 32em;
padding: var(--size-4-6);
cursor: default;
}
.strong-start-run-bottom {
display: flex;
flex: 0 0 auto;
flex-direction: column;
gap: var(--size-4-1);
padding-top: var(--size-4-2);
border-top: 1px solid var(--background-modifier-border);
}
.strong-start-run-bottom-tabs {
display: none;
align-items: center;
}
.strong-start-run-bottom.is-open .strong-start-run-bottom-tabs {
display: flex;
}
.strong-start-run-bottom-collapse {
margin-left: auto;
}
.strong-start-run-bottom-body {
display: none;
min-height: 0;
}
.strong-start-run-bottom.is-open .strong-start-run-bottom-body {
display: block;
}
.strong-start-run-log-history {
display: flex;
flex-direction: column;
gap: var(--size-2-2);
max-height: 35cqh;
overflow-y: auto;
padding-right: var(--size-4-1);
}
.strong-start-run-bottom.is-tab-notes .strong-start-run-log-history {
display: none;
}
.strong-start-run-log-row {
font-size: 0.9em;
}
.strong-start-run-log-time {
margin-right: var(--size-4-1);
color: var(--text-muted);
font-variant-numeric: tabular-nums;
}
.strong-start-run-notes-input {
display: none;
width: 100%;
max-height: 35cqh;
min-height: 8em;
resize: vertical;
font-size: inherit;
}
.strong-start-run-bottom.is-tab-notes .strong-start-run-notes-input {
display: block;
}
.strong-start-run-bottom-inputrow {
display: flex;
align-items: center;
gap: var(--size-4-1);
}
.strong-start-run-bottom.is-open.is-tab-notes .strong-start-run-bottom-inputrow {
display: none;
}
.strong-start-run-bottom.is-open .strong-start-run-bottom-expand {
display: none;
}
.strong-start-run-log-input {
width: 100%;
min-height: 44px;
}
.strong-start-run-dice-toast {
position: absolute;
inset: 0;
z-index: 5;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: fit-content;
height: fit-content;
margin: auto;
padding: var(--size-4-4) var(--size-4-6);
background-color: var(--background-secondary);
border-radius: var(--radius-l);
box-shadow: var(--shadow-s);
pointer-events: none;
animation: strong-start-run-dice-pop 200ms ease-out;
transition: opacity 300ms ease;
}
.strong-start-run-dice-toast-total {
font-size: 3em;
font-weight: var(--font-bold);
line-height: 1.1;
}
.strong-start-run-dice-toast-detail {
max-width: 18rem;
font-size: 1.1em;
text-align: center;
}
.strong-start-run-dice-toast.is-nat20 {
box-shadow: 0 0 0 4px var(--color-yellow);
}
.strong-start-run-dice-toast.is-nat1 {
animation:
strong-start-run-dice-pop 200ms ease-out,
strong-start-run-shake 400ms ease-in-out;
}
.strong-start-run-dice-toast.is-leaving {
opacity: 0;
}
@keyframes strong-start-run-dice-pop {
from {
transform: scale(0.6);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}
@keyframes strong-start-run-shake {
0%,
100% {
transform: translateX(0);
}
20% {
transform: translateX(-6px);
}
40% {
transform: translateX(6px);
}
60% {
transform: translateX(-4px);
}
80% {
transform: translateX(4px);
}
}
/* Must stay AFTER the toast rules above: the bare selector outranks the base
rule by source order alone, and the .is-nat1 pair covers the shake variant's
higher specificity — that ordering is what lets this skip !important. */
@media (prefers-reduced-motion: reduce) {
.strong-start-run-dice-toast,
.strong-start-run-dice-toast.is-nat1 {
animation: none;
transition: none;
}
}
/* ---- Settings: About -------------------------------------------------------- */
.strong-start-settings-about p {
color: var(--text-muted);
}
/* ---- Home: Dashboard/Foundation/Session zero sub-tabs (M8) ------------------ */
.strong-start-home-shell {
display: flex;
flex-direction: column;
gap: var(--size-4-3);
height: 100%;
}
.strong-start-home-body {
display: flex;
flex-direction: column;
flex: 1 1 auto;
gap: var(--size-4-4);
min-height: 0;
overflow-y: auto;
}
.strong-start-home-wizard-mount {
height: 100%;
}
/* ---- Fronts: shared pip control (Dashboard card + Foundation checkboxes) ---- */
.strong-start-fronts-card-list {
display: flex;
flex-direction: column;
gap: var(--size-4-2);
}
.strong-start-fronts-card-row {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: var(--size-4-2);
}
.strong-start-fronts-card-name {
font-weight: var(--font-semibold);
}
.strong-start-fronts-card-pips {
display: flex;
gap: var(--size-4-1);
}
.strong-start-fronts-pip {
flex: 0 0 auto;
width: var(--size-4-4);
height: var(--size-4-4);
padding: 0;
background-color: var(--background-modifier-border);
border: none;
border-radius: var(--radius-full);
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-fronts-pip:hover {
background-color: var(--text-faint);
}
.strong-start-fronts-pip.is-done {
background-color: var(--color-orange);
}
/* ---- Foundation sub-tab (M8) ------------------------------------------------ */
.strong-start-foundation-shell {
display: flex;
flex-direction: column;
gap: var(--size-4-4);
}
.strong-start-foundation-card-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--size-4-2);
}
.strong-start-foundation-card-header h3 {
margin: 0;
}
.strong-start-foundation-pitch-prose {
color: var(--text-normal);
}
.strong-start-front-card {
display: flex;
flex-direction: column;
gap: var(--size-4-2);
padding: var(--size-4-3);
margin-top: var(--size-4-2);
background-color: var(--background-primary);
border: 1px solid var(--background-modifier-border);
border-radius: var(--radius-m);
}
.strong-start-front-name-input {
font-weight: var(--font-semibold);
}
.strong-start-front-name-input,
.strong-start-front-goal-input,
.strong-start-front-doom-input,
.strong-start-front-portent-input {
width: 100%;
}
.strong-start-front-portents {
display: flex;
flex-direction: column;
gap: var(--size-4-1);
}
.strong-start-front-portent-row {
display: flex;
align-items: center;
gap: var(--size-4-2);
}
.strong-start-front-portent-row .strong-start-front-portent-input {
flex: 1 1 auto;
}
.strong-start-front-actions {
display: flex;
align-items: center;
gap: var(--size-4-2);
}
.strong-start-wizard-field-row {
display: flex;
align-items: center;
gap: var(--size-4-2);
}
.strong-start-wizard-field-row input {
flex: 1 1 auto;
}
.strong-start-list-row-dice {
flex: 0 0 auto;
}
/* ---- Campaign creation wizard (M8) ------------------------------------------ */
.strong-start-wizard-shell {
display: flex;
flex-direction: column;
gap: var(--size-4-4);
height: 100%;
max-width: 40rem;
margin: 0 auto;
}
.strong-start-wizard-dots {
justify-content: center;
}
.strong-start-progress-dot.is-active {
background-color: var(--interactive-accent);
box-shadow: 0 0 0 2px var(--background-secondary), 0 0 0 3px var(--interactive-accent);
}
.strong-start-wizard-content {
flex: 1 1 auto;
overflow-y: auto;
}
.strong-start-wizard-textarea {
width: 100%;
resize: vertical;
}
.strong-start-wizard-error {
color: var(--text-error);
}
.strong-start-wizard-quick-create {
margin-top: var(--size-4-4);
color: var(--text-muted);
font-size: var(--font-ui-smaller);
}
.strong-start-wizard-truths {
display: flex;
flex-direction: column;
gap: var(--size-4-1);
}
.strong-start-wizard-truth-row {
display: flex;
align-items: center;
gap: var(--size-4-2);
}
.strong-start-wizard-truth-number {
flex: 0 0 auto;
width: 1.5em;
color: var(--text-muted);
text-align: right;
}
.strong-start-wizard-truth-input {
flex: 1 1 auto;
}
.strong-start-wizard-party-row {
display: flex;
align-items: center;
gap: var(--size-4-2);
margin-bottom: var(--size-4-1);
}
.strong-start-wizard-party-input {
flex: 1 1 auto;
}
.strong-start-wizard-summary {
display: flex;
flex-direction: column;
gap: var(--size-4-1);
}
.strong-start-wizard-nav {
display: flex;
align-items: center;
justify-content: space-between;
flex: 0 0 auto;
gap: var(--size-4-2);
padding-top: var(--size-4-3);
border-top: 1px solid var(--background-modifier-border);
}
.strong-start-wizard-nav-right {
display: flex;
gap: var(--size-4-2);
}
/* ---- Dashboard: session-zero nudge (M9) ------------------------------------- */
.strong-start-session-zero-nudge {
color: var(--text-muted);
font-size: var(--font-ui-smaller);
}
/* ---- Home: Session zero sub-tab (M9) ---------------------------------------- */
.strong-start-session-zero-shell {
display: flex;
flex-direction: column;
gap: var(--size-4-3);
}
.strong-start-session-zero-progress {
color: var(--text-muted);
font-weight: var(--font-medium);
}
.strong-start-session-zero-pitch-prose {
margin-bottom: var(--size-4-2);
color: var(--text-normal);
}
.strong-start-session-zero-items {
display: flex;
flex-direction: column;
gap: var(--size-4-1);
margin-top: var(--size-4-2);
}
.strong-start-session-zero-item {
display: flex;
align-items: flex-start;
gap: var(--size-4-2);
min-height: 44px;
padding: var(--size-4-1) var(--size-4-2);
border-radius: var(--radius-m);
cursor: var(--cursor-link);
}
.strong-start-session-zero-item:hover {
background-color: var(--background-modifier-hover);
}
.strong-start-session-zero-check {
display: flex;
flex: 0 0 auto;
align-items: center;
margin-top: 2px;
color: var(--text-muted);
background: transparent;
border: none;
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-session-zero-check.is-done {
color: var(--text-success);
}
.strong-start-session-zero-item-text {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
}
.strong-start-session-zero-item-label {
color: var(--text-normal);
font-weight: var(--font-medium);
}
.strong-start-session-zero-item.is-done .strong-start-session-zero-item-label {
color: var(--text-muted);
text-decoration: line-through;
}
.strong-start-session-zero-item-detail {
color: var(--text-muted);
font-size: var(--font-ui-smaller);
}
.strong-start-session-zero-safety-copy h4 {
margin: var(--size-4-3) 0 var(--size-4-1);
}
.strong-start-session-zero-safety-copy p {
margin: 0;
color: var(--text-muted);
}
/* ---- Roster level stepper (Characters step, M10) ---------------------------- */
.strong-start-roster-row {
display: flex;
align-items: center;
gap: var(--size-4-3);
}
.strong-start-roster-level {
display: flex;
align-items: center;
gap: var(--size-4-1);
color: var(--text-muted);
}
.strong-start-roster-level-label {
font-size: var(--font-ui-smaller);
}
/* ---- Stepper control (panel-kit.ts renderStepper, M10) ---------------------- */
.strong-start-stepper {
display: flex;
align-items: center;
gap: var(--size-4-1);
}
.strong-start-stepper-btn {
display: flex;
flex: 0 0 auto;
align-items: center;
justify-content: center;
width: var(--size-4-7);
min-height: var(--size-4-7);
padding: 0;
}
.strong-start-stepper-value {
min-width: 1.5em;
text-align: center;
color: var(--text-normal);
font-variant-numeric: tabular-nums;
}
/* ---- 5e module (M10): benchmark card, DC/damage/stats tables, dials --------- */
.strong-start-dnd5e-benchmark-card {
display: flex;
flex-direction: column;
gap: var(--size-4-2);
padding: var(--size-4-3);
background-color: var(--background-secondary);
border-radius: var(--radius-m);
}
.strong-start-dnd5e-benchmark-summary {
font-weight: var(--font-semibold);
color: var(--text-normal);
}
.strong-start-dnd5e-benchmark-readout {
color: var(--text-normal);
}
.strong-start-dnd5e-benchmark-manual h4 {
margin: var(--size-4-2) 0 0;
}
.strong-start-dnd5e-benchmark-manual-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--size-4-2);
max-width: 16em;
}
.strong-start-dnd5e-dc-row {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--size-4-2);
}
.strong-start-dnd5e-dc-band {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--size-4-1);
padding: var(--size-4-2);
text-align: center;
background-color: var(--background-secondary);
border-radius: var(--radius-m);
}
.strong-start-dnd5e-dc-value {
font-weight: var(--font-semibold);
font-size: var(--font-ui-larger);
}
.strong-start-dnd5e-dc-name {
color: var(--text-muted);
font-size: var(--font-ui-smaller);
}
.strong-start-dnd5e-table {
width: 100%;
border-collapse: collapse;
}
.strong-start-dnd5e-table th,
.strong-start-dnd5e-table td {
padding: var(--size-4-1) var(--size-4-2);
text-align: left;
border-bottom: 1px solid var(--background-modifier-border);
}
.strong-start-dnd5e-dials-list {
display: flex;
flex-direction: column;
gap: var(--size-4-2);
}
.strong-start-dnd5e-dial-name {
font-weight: var(--font-semibold);
color: var(--text-normal);
}
.strong-start-dnd5e-dial-desc {
color: var(--text-muted);
font-size: var(--font-ui-smaller);
}
/* ---- Run mode: 5e drawer (M10) ---------------------------------------------- */
.strong-start-run-dnd5e-drawer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
z-index: 15;
display: flex;
flex-direction: column;
width: min(24em, 90%);
padding: var(--size-4-4);
overflow-y: auto;
background-color: var(--background-primary);
border-left: 1px solid var(--background-modifier-border);
box-shadow: var(--shadow-l);
transform: translateX(100%);
transition: transform 200ms ease;
}
.strong-start-run-dnd5e-drawer.is-open {
transform: translateX(0);
}
@media (prefers-reduced-motion: reduce) {
.strong-start-run-dnd5e-drawer {
transition: none;
}
}
.strong-start-run-dnd5e-drawer-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--size-4-2);
margin-bottom: var(--size-4-3);
}
.strong-start-run-dnd5e-drawer-header h3 {
margin: 0;
}
.strong-start-run-dnd5e-drawer-body {
display: flex;
flex-direction: column;
gap: var(--size-4-2);
}
/* ---- Dismissible hints (M11) ------------------------------------------------- */
.strong-start-hint-row {
display: flex;
align-items: flex-start;
gap: var(--size-4-2);
padding: var(--size-4-2) var(--size-4-3);
color: var(--text-muted);
font-size: var(--font-ui-small);
background-color: var(--background-secondary);
border-left: 2px solid var(--interactive-accent);
border-radius: var(--radius-m);
}
.strong-start-hint-row-icon {
display: flex;
flex: 0 0 auto;
margin-top: 2px;
color: var(--text-accent);
}
.strong-start-hint-row-text {
flex: 1 1 auto;
min-width: 0;
}
.strong-start-hint-row-close {
display: flex;
flex: 0 0 auto;
align-items: center;
justify-content: center;
padding: 0;
width: var(--size-4-6);
height: var(--size-4-6);
color: var(--text-faint);
background: transparent;
border: none;
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-hint-row-close:hover {
color: var(--text-normal);
}
/* ---- Welcome modal (M11) ----------------------------------------------------- */
.strong-start-welcome-modal .strong-start-welcome-tagline {
color: var(--text-muted);
}
.strong-start-welcome-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
gap: var(--size-4-3);
margin: var(--size-4-4) 0;
}
.strong-start-welcome-card {
display: flex;
flex-direction: column;
gap: var(--size-4-1);
padding: var(--size-4-3);
text-align: center;
background-color: var(--background-secondary);
border-radius: var(--radius-m);
}
.strong-start-welcome-card-icon {
display: flex;
align-items: center;
justify-content: center;
color: var(--text-accent);
}
.strong-start-welcome-card-label {
font-weight: var(--font-semibold);
color: var(--text-normal);
}
.strong-start-welcome-card-desc {
color: var(--text-muted);
font-size: var(--font-ui-smaller);
}
.strong-start-welcome-attribution {
color: var(--text-faint);
font-size: var(--font-ui-smaller);
}
.strong-start-welcome-buttons {
display: flex;
justify-content: flex-end;
margin-top: var(--size-4-4);
}
/* ---- Help panel (M11) --------------------------------------------------------- */
.strong-start-help-shell {
display: flex;
flex-direction: column;
gap: var(--size-4-4);
}
.strong-start-help-loop-list {
margin: 0;
padding-left: var(--size-4-4);
}
.strong-start-help-steps-list {
display: flex;
flex-direction: column;
gap: var(--size-4-1);
}
.strong-start-help-step-row {
display: flex;
align-items: baseline;
gap: var(--size-4-2);
}
.strong-start-help-step-label {
flex: 0 0 auto;
width: 12rem;
font-weight: var(--font-medium);
color: var(--text-normal);
}
.strong-start-help-shortcuts-list {
display: flex;
flex-direction: column;
gap: var(--size-4-2);
}
.strong-start-help-shortcut-row {
display: flex;
align-items: center;
gap: var(--size-4-2);
}
.strong-start-help-shortcut-row kbd {
padding: var(--size-4-1) var(--size-4-2);
color: var(--text-normal);
background-color: var(--background-secondary);
border-radius: var(--radius-s);
}
.strong-start-help-links-row {
display: flex;
gap: var(--size-4-3);
margin-top: var(--size-4-2);
}
/* ---- Home / Sessions list (M13) ------------------------------------------------ */
.strong-start-session-list {
display: flex;
flex-direction: column;
}
.strong-start-session-row {
display: flex;
align-items: center;
gap: var(--size-4-3);
min-height: 44px;
padding: var(--size-4-1) var(--size-4-2);
border-radius: var(--radius-m);
cursor: var(--cursor-link);
}
.strong-start-session-row:hover {
background-color: var(--background-modifier-hover);
}
.strong-start-session-row-title {
flex: 1 1 auto;
min-width: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.strong-start-session-row-number {
font-weight: var(--font-medium);
}
.strong-start-session-row-name {
color: var(--text-muted);
}
.strong-start-session-row-meta {
display: flex;
flex: 0 0 auto;
align-items: center;
gap: var(--size-4-2);
color: var(--text-muted);
font-size: var(--font-ui-smaller);
}
.strong-start-session-status {
padding: 1px var(--size-4-2);
border-radius: var(--radius-s);
background-color: var(--background-modifier-hover);
}
.strong-start-session-status.is-played {
color: var(--text-on-accent);
background-color: var(--interactive-accent);
}
.strong-start-session-recap {
color: var(--text-faint);
}
/* ---- Delight details (M13) -----------------------------------------------------
Prep timer, dice tumble, secret reveal flip. Motion is garnish: every
animation here is disabled under prefers-reduced-motion. */
.strong-start-prep-timer {
color: var(--text-faint);
font-size: var(--font-ui-smaller);
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.strong-start-roll-chip-die {
display: inline-flex;
color: var(--text-accent);
animation: strong-start-dice-tumble 300ms ease-out;
}
@keyframes strong-start-dice-tumble {
0% {
transform: rotate(-140deg) scale(0.6);
}
70% {
transform: rotate(15deg) scale(1.05);
}
100% {
transform: rotate(0deg) scale(1);
}
}
.strong-start-run-secret-card.is-flipping {
animation: strong-start-secret-flip 260ms ease-out;
transform-style: preserve-3d;
}
@keyframes strong-start-secret-flip {
0% {
transform: rotateX(-90deg);
opacity: 0.4;
}
100% {
transform: rotateX(0deg);
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.strong-start-roll-chip-die,
.strong-start-run-secret-card.is-flipping {
animation: none;
}
}
/* ---- Home / World entity list + entity editor (M17) ----------------------------- */
.strong-start-world-shell {
display: flex;
flex-direction: column;
gap: var(--size-4-2);
}
.strong-start-world-list {
display: flex;
flex-direction: column;
}
.strong-start-world-row {
display: flex;
align-items: center;
gap: var(--size-4-2);
min-height: 44px;
padding: var(--size-4-1) var(--size-4-2);
border-radius: var(--radius-m);
cursor: var(--cursor-link);
}
.strong-start-world-row:hover {
background-color: var(--background-modifier-hover);
}
.strong-start-world-row-title {
flex: 1 1 auto;
min-width: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.strong-start-world-row-name {
font-weight: var(--font-medium);
}
.strong-start-world-row-meta {
color: var(--text-muted);
font-size: var(--font-ui-small);
}
.strong-start-world-row.is-quest-done .strong-start-world-row-name {
color: var(--text-muted);
text-decoration: line-through;
}
.strong-start-world-quest-toggle {
display: flex;
flex: 0 0 auto;
align-items: center;
justify-content: center;
min-width: 32px;
min-height: 32px;
padding: 0;
color: var(--text-muted);
background: transparent;
border: none;
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-world-quest-toggle.is-done {
color: var(--text-accent);
}
.strong-start-world-new {
align-self: flex-start;
margin-top: var(--size-4-1);
}
.strong-start-entity-editor-footer {
display: flex;
justify-content: flex-start;
margin-top: var(--size-4-2);
}
.strong-start-foundation-system-row {
display: flex;
align-items: center;
gap: var(--size-4-3);
}
.strong-start-session-zero-section {
position: relative;
margin-bottom: var(--size-4-2);
}
.strong-start-session-zero-section > .strong-start-icon-button {
position: absolute;
top: 0;
right: 0;
}
.strong-start-session-zero-section-prose {
padding-right: var(--size-4-8);
}
/* Chip pencil (M17): compact inside the chip, but still a touch target. */
.strong-start-chip .strong-start-chip-edit {
min-width: 28px;
min-height: 28px;
padding: 0;
}
body.is-phone .strong-start-chip .strong-start-chip-edit {
min-width: 40px;
min-height: 40px;
}
/* ---- End-session stars & wishes (M16) ------------------------------------------ */
.strong-start-end-session-feedback {
width: 100%;
margin-top: var(--size-4-2);
}
/* ---- Phone shell (M12) --------------------------------------------------------
Bottom tab bar replaces the icon rail on phones; nav placements come from
nav-model.ts (PHONE_BAR / PHONE_MORE_SHEET). Hidden by default — desktop and
tablet keep the rail. */
.strong-start-bottombar {
display: none;
}
body.is-phone .strong-start-rail {
display: none;
}
body.is-phone .strong-start-bottombar {
display: flex;
align-items: stretch;
flex-shrink: 0;
border-top: 1px solid var(--background-modifier-border);
background: var(--background-secondary);
padding-bottom: env(safe-area-inset-bottom);
/* Lifted at runtime to sit flush above Obsidian's global mobile navbar
(PhoneShell.alignAboveNavbar measures the overlap). */
margin-bottom: var(--strong-start-navbar-lift, 0px);
}
.strong-start-bottombar-tab {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2px;
min-width: 44px;
min-height: 56px;
padding: 0;
cursor: var(--cursor-link);
color: var(--text-muted);
font-size: var(--font-ui-smaller);
}
/* Obsidian's mobile theme styles bare <button>s as rounded, filled capsules
(`.is-mobile button` out-specifies a plain class). Override under
body.is-phone so the tabs read as one flat bar, not pills on a rectangle. */
body.is-phone .strong-start-bottombar-tab,
body.is-phone .strong-start-bottombar-tab:hover,
body.is-phone .strong-start-bottombar-tab:focus {
background-color: transparent;
border: none;
border-radius: 0;
box-shadow: none;
}
body.is-phone .strong-start-bottombar-tab:active {
background-color: var(--background-modifier-hover);
}
body.is-phone .strong-start-bottombar-tab.is-active {
color: var(--text-accent);
box-shadow: inset 0 2px 0 0 var(--interactive-accent);
}
.strong-start-bottombar-icon .svg-icon {
width: 20px;
height: 20px;
}
.strong-start-bottombar-label {
line-height: 1;
}
/* Android WebView bug (found on-device in Inkswell): when Obsidian shrinks its
app container for the soft keyboard, flex-stretch and percentage heights
resolve stale inside the shrunken subtree — the main column collapses to its
content height, leaving a keyboard-sized void. Absolute positioning resolves
against the view's (correct) rect and dodges the bug. Phone-only: the rail
is display:none there, so inset:0 overlays nothing. */
body.is-phone .strong-start-view {
position: relative;
}
body.is-phone .strong-start-main {
position: absolute;
inset: 0;
}
/* KeyboardWatcher publishes --strong-start-keyboard-inset + is-keyboard-open
on the view. Obsidian itself shrinks the app container while an input is
focused, so content isn't covered — but the bottom bar staying in the flex
column (with its navbar lift) squeezes the content to nothing. While typing,
the bar gets out of the way; tab-switching mid-edit isn't a flow to protect. */
body.is-phone .strong-start-view.is-keyboard-open .strong-start-bottombar {
display: none;
}
/* Header on narrow widths: the campaign selector takes the free space and
truncates inside itself instead of pushing the ⋯ menu off-screen. */
body.is-phone .strong-start-header-selector {
flex: 1 1 auto;
min-width: 0;
}
body.is-phone .strong-start-header-selector select {
width: 100%;
max-width: 100%;
}
/* Form fields at ≥16px: sub-16px focused inputs trigger auto-zoom in mobile
webviews (the "field takes over the screen" effect). */
body.is-phone .strong-start-view input[type="text"],
body.is-phone .strong-start-view textarea,
body.is-phone .strong-start-view select {
font-size: max(16px, var(--font-ui-medium));
}
/* ---- Phone: prep master→detail (M12) ------------------------------------------
The step list is a full-width screen; tapping a step opens the workspace
full-screen with a back header. The board's `is-phone-detail` class picks
the screen; the @container narrow rules above are overridden here (a phone
is always under the 700px container threshold). */
.strong-start-phone-back-header {
display: none;
}
body.is-phone .strong-start-prep-board {
flex-direction: column;
}
body.is-phone .strong-start-prep-master {
flex-direction: column;
width: 100%;
overflow-x: visible;
overflow-y: auto;
border-right: none;
border-bottom: none;
}
body.is-phone .strong-start-step-row {
min-height: 44px;
}
body.is-phone .strong-start-prep-workspace {
display: none;
padding-left: 0;
}
body.is-phone .strong-start-prep-board.is-phone-detail .strong-start-prep-master {
display: none;
}
body.is-phone .strong-start-prep-board.is-phone-detail .strong-start-prep-workspace {
display: block;
}
body.is-phone .strong-start-phone-back-header {
display: flex;
align-items: center;
gap: var(--size-4-2);
padding-bottom: var(--size-4-2);
margin-bottom: var(--size-4-2);
border-bottom: 1px solid var(--background-modifier-border);
}
.strong-start-phone-back-button {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 44px;
min-height: 44px;
padding: 0;
color: var(--text-normal);
background: none;
border: none;
box-shadow: none;
cursor: var(--cursor-link);
}
.strong-start-phone-back-title {
font-weight: var(--font-semibold);
}
/* ---- Phone: run mode (M12) -----------------------------------------------------
The container query already stacks the board single-column; this compacts
the sticky top bar so the timer, dice, safety, and End all fit one row. */
body.is-phone .strong-start-run-topbar {
flex-wrap: nowrap;
gap: var(--size-4-1);
}
body.is-phone .strong-start-run-session-label {
flex: 0 0 auto;
font-size: var(--font-ui-small);
}
/* The header above already names the campaign — drop the duplicate here. */
body.is-phone .strong-start-run-session-campaign {
display: none;
}
body.is-phone .strong-start-run-icon-button {
min-width: 40px;
min-height: 40px;
}
body.is-phone .strong-start-run-end-button {
padding: var(--size-4-1) var(--size-4-2);
font-size: var(--font-ui-small);
}
/* The bottom pane rides above the soft keyboard: Obsidian shrinks the app
container, and with the bottom bar hidden while typing the flex column's
natural bottom IS the keyboard top. Safe-area padding for the no-keyboard
case. */
body.is-phone .strong-start-run-bottom {
padding-bottom: env(safe-area-inset-bottom);
}
/* An expanded log history would squeeze the board to nothing behind the soft
keyboard while typing a log line — hide it until the keyboard drops. */
body.is-phone .strong-start-view.is-keyboard-open .strong-start-run-log-history {
display: none;
}
/* ---- 5e Monster Builder (M18) ------------------------------------------- */
/* Reference tables can outgrow the drawer/prep column — scroll inside their
own wrapper, never the page. */
.strong-start-dnd5e-table-scroll {
overflow-x: auto;
}
.strong-start-dnd5e-table-toggle {
display: inline-block;
margin-top: var(--size-4-1);
font-size: var(--font-ui-smaller);
}
.strong-start-dnd5e-table-filter {
width: 100%;
margin-bottom: var(--size-4-2);
}
.strong-start-dnd5e-location-select {
margin-bottom: var(--size-4-2);
}
.strong-start-run-dnd5e-build-row,
.strong-start-monster-build-row {
display: flex;
align-items: center;
gap: var(--size-4-2);
margin: var(--size-4-2) 0;
flex-wrap: wrap;
}
/* Builder modal */
.strong-start-monster-builder {
max-height: 80vh;
overflow-y: auto;
}
.strong-start-monster-presets-row {
display: flex;
flex-wrap: wrap;
gap: var(--size-4-1);
margin-bottom: var(--size-4-2);
}
.strong-start-monster-preset {
font-size: var(--font-ui-smaller);
}
.strong-start-monster-party-row {
display: flex;
align-items: center;
gap: var(--size-4-2);
margin: var(--size-4-1) 0 var(--size-4-2);
flex-wrap: wrap;
}
.strong-start-monster-field-label {
display: block;
font-size: var(--font-ui-small);
font-weight: var(--font-semibold);
margin-bottom: var(--size-4-1);
}
.strong-start-monster-abilities {
margin: var(--size-4-2) 0;
}
.strong-start-monster-chip {
font-size: var(--font-ui-smaller);
margin-right: var(--size-4-1);
opacity: 0.7;
}
.strong-start-monster-chip.is-active {
opacity: 1;
background-color: var(--interactive-accent);
color: var(--text-on-accent);
}
.strong-start-monster-features {
margin: var(--size-4-2) 0;
}
.strong-start-monster-feature-row label {
display: flex;
align-items: baseline;
gap: var(--size-4-1);
font-size: var(--font-ui-small);
cursor: pointer;
}
.strong-start-monster-preview {
border: 1px solid var(--background-modifier-border);
border-radius: var(--radius-s);
padding: var(--size-4-2);
margin: var(--size-4-2) 0;
background-color: var(--background-secondary);
}
.strong-start-monster-preview-title {
font-weight: var(--font-semibold);
}
.strong-start-monster-preview-flavor {
font-style: italic;
font-size: var(--font-ui-small);
color: var(--text-muted);
}
.strong-start-monster-preview-stats {
font-size: var(--font-ui-small);
margin-top: var(--size-4-1);
}
.strong-start-monster-preview-feature {
font-size: var(--font-ui-smaller);
color: var(--text-muted);
margin-top: var(--size-4-1);
}
/* The preview is a luxury on a phone-width modal — keep it, but compact. */
@media (max-width: 500px) {
.strong-start-monster-preview-feature {
display: none;
}
}