/* dmtools project styles. Bootstrap + DataTables (bs5) are imported from app.js. */ body { min-height: 100vh; } main.app-main { padding-top: 1.5rem; padding-bottom: 3rem; } .navbar-brand { font-weight: 600; letter-spacing: 0.02em; } .login-card { max-width: 24rem; margin: 8vh auto 0; } /* Let DataTables' controls breathe inside a Bootstrap card. */ table.dataTable { width: 100% !important; } /* --- Family tree --------------------------------------------------------- */ .family-tree, .family-tree ul { list-style: none; margin: 0; padding-left: 1.25rem; } .family-tree { padding-left: 0; } .family-tree li { position: relative; padding: 0.15rem 0 0.15rem 1rem; } .family-tree ul > li::before { /* elbow connector */ content: ""; position: absolute; top: 0; left: 0; bottom: 50%; width: 0.75rem; border-left: 1px solid var(--bs-border-color); border-bottom: 1px solid var(--bs-border-color); } .family-tree ul > li::after { /* line continuing to siblings below */ content: ""; position: absolute; top: 0; left: 0; height: 100%; border-left: 1px solid var(--bs-border-color); } .family-tree ul > li:last-child::after { display: none; } .ft-couple { display: inline-flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; } .ft-person { display: inline-flex; align-items: center; gap: 0.45rem; padding: 0.2rem 0.5rem; border: 1px solid var(--bs-border-color); border-radius: 0.375rem; text-decoration: none; color: inherit; background: var(--bs-body-bg); } .ft-person:hover { border-color: var(--bs-primary); } .ft-name { font-weight: 500; } .ft-meta { font-size: 0.8125rem; color: var(--bs-secondary-color); } .ft-amp { color: var(--bs-secondary-color); } /* --- Art gallery ------------------------------------------------------- */ .art-thumb { height: 180px; display: flex; align-items: center; justify-content: center; padding: 0.4rem; background: var(--bs-tertiary-bg); border-bottom: 1px solid var(--bs-border-color); border-top-left-radius: inherit; border-top-right-radius: inherit; overflow: hidden; } .art-thumb img { max-width: 100%; max-height: 100%; object-fit: contain; /* whole image, never cropped */ } .art-full img { max-width: 100%; height: auto; } /* Drag-to-reorder handle, top-left of each tile */ .art-drag-handle { position: absolute; top: 0.35rem; left: 0.35rem; z-index: 2; width: 1.9rem; height: 1.9rem; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--bs-border-color); border-radius: 0.35rem; background: var(--bs-body-bg); color: var(--bs-secondary-color); opacity: 0.8; cursor: grab; line-height: 1; } .art-drag-handle:hover { opacity: 1; color: var(--bs-body-color); } .art-drag-handle:active { cursor: grabbing; } .art-tile.is-dragging { opacity: 0.4; } .art-tile.is-drag-over .card { outline: 2px dashed var(--bs-primary); outline-offset: 2px; } .art-reorder-status { position: fixed; right: 1rem; bottom: 1rem; z-index: 1080; padding: 0.4rem 0.85rem; border-radius: 2rem; background: var(--bs-body-color); color: var(--bs-body-bg); font-size: 0.85rem; opacity: 0; pointer-events: none; transition: opacity 0.2s ease; } .art-reorder-status.is-visible { opacity: 0.92; } .art-reorder-status.is-error { background: var(--bs-danger); color: #fff; } /* --- Character sheets -------------------------------------------------- */ .min-w-0 { min-width: 0; } .char-portrait { display: flex; align-items: center; justify-content: center; background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); border-radius: 0.5rem; overflow: hidden; } .char-portrait img { width: 100%; height: 100%; object-fit: contain; } .char-portrait--card { height: 150px; border-radius: 0.375rem 0.375rem 0 0; border-width: 0 0 1px; } .char-portrait--hero { height: 220px; margin-bottom: 1rem; } .char-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr)); gap: 0.5rem 1.25rem; margin-bottom: 1rem; padding: 0.85rem 1rem; background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); border-radius: 0.5rem; } .char-meta > div { display: flex; flex-direction: column; } .char-meta dt { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--bs-secondary-color); } .char-meta dd { margin: 0.05rem 0 0; font-weight: 500; } .char-ability-table td:first-child, .char-ability-table th:first-child, .char-skill-table td:first-child, .char-skill-table th:first-child { white-space: nowrap; } .char-ability-table tr.is-proficient, .char-skill-table tr.is-proficient { font-weight: 600; } .char-ability-table tr.is-proficient td:first-child, .char-skill-table tr.is-proficient td:first-child { box-shadow: inset 2px 0 0 var(--bs-primary); padding-left: 0.5rem; } .char-skill-table { font-size: 0.875rem; } /* --- Tracker: unfoldable stat blocks --------------------------------- */ [data-bs-toggle="collapse"] .sb-caret { display: inline-block; transition: transform 0.15s ease; } [data-bs-toggle="collapse"][aria-expanded="true"] .sb-caret { transform: rotate(90deg); } .statblock-collapse h3 { margin-top: 0.75rem; } /* --- Overview tiles ------------------------------------------------------ */ .home-tile { transition: border-color 0.12s ease, transform 0.12s ease; } .home-tile:hover { border-color: var(--bs-primary); transform: translateY(-2px); } /* --- Storyline: chapter index ----------------------------------------- */ .storyline-chapter-list { display: grid; gap: 0.75rem; max-width: 60rem; } .storyline-chapter-card { display: flex; align-items: flex-start; gap: 1rem; padding: 1rem 1.25rem; border: 1px solid var(--bs-border-color); border-radius: 0.5rem; background: var(--bs-body-bg); text-decoration: none; color: inherit; transition: border-color 0.12s ease, transform 0.12s ease; } .storyline-chapter-card:hover { border-color: var(--bs-primary); transform: translateY(-2px); } .storyline-chapter-num { flex: 0 0 auto; width: 2rem; height: 2rem; display: grid; place-items: center; border-radius: 50%; background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); font-variant-numeric: tabular-nums; font-weight: 600; } .storyline-chapter-body { flex: 1 1 auto; min-width: 0; } .storyline-chapter-title { display: block; font-size: 1.125rem; font-weight: 600; } .storyline-chapter-summary { display: block; color: var(--bs-secondary-color); font-size: 0.9375rem; margin-top: 0.15rem; } .storyline-chapter-go { align-self: center; color: var(--bs-secondary-color); font-size: 1.25rem; } /* --- Storyline: chapter layout + table of contents ------------------- */ .storyline-toc { position: sticky; top: 0.25rem; font-size: 0.9375rem; } .storyline-toc-link { display: flex; gap: 0.5rem; padding: 0.3rem 0.5rem; border-radius: 0.375rem; border-left: 2px solid transparent; text-decoration: none; color: var(--bs-secondary-color); } .storyline-toc-link:hover { color: var(--bs-body-color); background: var(--bs-tertiary-bg); } .storyline-toc-link.is-active { color: var(--bs-body-color); border-left-color: var(--bs-primary); background: var(--bs-tertiary-bg); font-weight: 600; } .storyline-toc-num { font-variant-numeric: tabular-nums; color: var(--bs-secondary-color); } /* Unfoldable per-chapter section lists */ .storyline-toc-row { display: flex; align-items: flex-start; gap: 0.15rem; } .storyline-toc-row .storyline-toc-link { flex: 1 1 auto; min-width: 0; } .storyline-toc-fold { flex: 0 0 1.4rem; height: 1.9rem; padding: 0; border: 0; background: none; color: var(--bs-secondary-color); cursor: pointer; transition: transform 0.15s ease; } button.storyline-toc-fold:hover { color: var(--bs-body-color); } .storyline-toc-item.is-open > .storyline-toc-row > button.storyline-toc-fold { transform: rotate(90deg); } .storyline-toc-sections { display: none; margin: 0.1rem 0 0.4rem 1.4rem; padding: 0; max-height: 45vh; overflow-y: auto; scrollbar-width: none; font-size: 0.875rem; } .storyline-toc-sections::-webkit-scrollbar { display: none; } .storyline-toc-item.is-open > .storyline-toc-sections { display: block; } .storyline-toc-sub { display: flex; gap: 0.5rem; padding: 0.2rem 0.5rem; border-left: 2px solid var(--bs-border-color); text-decoration: none; color: var(--bs-secondary-color); } .storyline-toc-sub:hover { color: var(--bs-body-color); background: var(--bs-tertiary-bg); } .storyline-toc-sub.is-current { color: var(--bs-body-color); border-left-color: var(--bs-primary); font-weight: 600; } .storyline-toc-sub .storyline-toc-num { flex: 0 0 1.4rem; } .storyline-section { scroll-margin-top: 0.75rem; } /* --- Storyline: the document itself --------------------------------- */ .storyline-doc { max-width: 46rem; font-size: 1.05rem; line-height: 1.7; } .storyline-doc-head { margin-bottom: 2.5rem; padding-bottom: 1.25rem; border-bottom: 1px solid var(--bs-border-color); } .storyline-eyebrow { text-transform: uppercase; letter-spacing: 0.09em; font-size: 0.8rem; font-weight: 700; color: var(--bs-primary); } .storyline-doc-head h1 { margin: 0.35rem 0 0.5rem; font-size: clamp(1.9rem, 4vw, 2.6rem); line-height: 1.15; } .storyline-standfirst { font-size: 1.15rem; color: var(--bs-secondary-color); font-style: italic; margin: 0; } .storyline-doc p { margin: 0 0 1.1rem; } .storyline-doc u { text-underline-offset: 0.18em; text-decoration-thickness: 1px; } .storyline-section { display: flex; align-items: baseline; gap: 0.75rem; margin: 2.75rem 0 1rem; padding-top: 1.25rem; border-top: 1px solid var(--bs-border-color); font-size: 1.45rem; line-height: 1.25; } .storyline-section span { flex: 0 0 auto; font-variant-numeric: tabular-nums; font-size: 0.9rem; font-weight: 700; color: var(--bs-primary); padding-top: 0.35rem; } .storyline-lead { font-size: 1.15rem; } .storyline-lead::first-letter { /* subtle emphasis on the opening line of a section */ font-weight: 600; } .storyline-turn { font-size: 1.2rem; font-weight: 600; text-align: center; margin: 1.75rem 0 !important; } /* Pull-quotes for in-world spoken lines */ .storyline-quote { margin: 1.5rem 0; padding: 0.6rem 0 0.6rem 1.25rem; border-left: 3px solid var(--bs-primary); font-size: 1.2rem; font-style: italic; color: var(--bs-body-color); } .storyline-quote::before { content: "\201C"; } .storyline-quote::after { content: "\201D"; } .storyline-quote--close { border-left: 0; text-align: center; font-size: 1.3rem; padding: 1.5rem 1rem; margin-top: 2.5rem; border-top: 1px solid var(--bs-border-color); } /* GM callouts */ .storyline-callout { position: relative; margin: 1.75rem 0; padding: 1.1rem 1.25rem 1.1rem 1.25rem; background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); border-left: 3px solid var(--bs-info, #6ea8fe); border-radius: 0.4rem; } .storyline-callout > :last-child { margin-bottom: 0; } .storyline-callout::before { content: attr(data-label); display: block; text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.72rem; font-weight: 700; color: var(--bs-secondary-color); margin-bottom: 0.4rem; } .storyline-callout--warn { border-left-color: var(--bs-warning, #ffc107); } /* The escalation ladder in the Final Crisis */ .storyline-ladder { margin: 1.25rem 0; padding-left: 0; list-style: none; counter-reset: rung; } .storyline-ladder li { counter-increment: rung; position: relative; padding: 0.55rem 0.9rem 0.55rem 2.75rem; margin-bottom: 0.4rem; background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); border-radius: 0.375rem; font-style: italic; } .storyline-ladder li::before { content: counter(rung); position: absolute; left: 0.9rem; font-style: normal; font-weight: 700; color: var(--bs-primary); } /* Quick-reference panels (numbers + cast) */ .storyline-ref { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); margin-bottom: 2.5rem; } .storyline-ref-panel { padding: 1.1rem 1.25rem; background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); border-radius: 0.5rem; font-size: 0.95rem; line-height: 1.5; } .storyline-ref-panel h3 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--bs-secondary-color); margin: 0 0 0.75rem; } .storyline-ref-panel dl { margin: 0; } .storyline-ref-panel dl > div { display: flex; gap: 0.6rem; padding: 0.2rem 0; } .storyline-ref-panel dt { flex: 0 0 6.5rem; font-variant-numeric: tabular-nums; color: var(--bs-body-color); } .storyline-ref-panel dd { margin: 0; color: var(--bs-secondary-color); } .storyline-ref-panel ul { margin: 0; padding-left: 1.1rem; } .storyline-ref-panel li { margin-bottom: 0.5rem; } .storyline-ref-panel li:last-child { margin-bottom: 0; } /* Chapter pager */ .storyline-pager { display: flex; justify-content: space-between; gap: 1rem; margin-top: 3rem; padding-top: 1.25rem; border-top: 1px solid var(--bs-border-color); } .storyline-pager-link { display: flex; flex-direction: column; gap: 0.15rem; text-decoration: none; color: inherit; padding: 0.5rem 0.75rem; border: 1px solid var(--bs-border-color); border-radius: 0.4rem; max-width: 48%; } .storyline-pager-link:hover { border-color: var(--bs-primary); } .storyline-pager-dir { font-size: 0.8rem; color: var(--bs-secondary-color); } .storyline-pager-title { font-weight: 600; } /* --- Storyline chapter page: split view (content above, notes docked) --- */ /* On wide/tall screens the chapter page fills the viewport: the top pane scrolls the chapter, the bottom pane is a fixed-height notes dock. Falls back to normal document flow on small screens (see media query below). */ .storyline-chapter-page { overflow: hidden; } .storyline-chapter-page main.app-main { min-height: 0; padding: 0; height: calc(100vh - var(--app-nav-h, 3.5rem)); height: calc(100dvh - var(--app-nav-h, 3.5rem)); } .storyline-chapter-page main.app-main > .container { height: 100%; display: flex; flex-direction: column; padding-top: 0.75rem; } .storyline-split { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; /* --notes-h is set by the resize handle; default is one third */ --notes-h: 33%; } .storyline-split-main { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; padding-bottom: 1.5rem; /* Scroll stays available; the bar is just hidden. */ scrollbar-width: none; /* Firefox */ -ms-overflow-style: none; /* legacy Edge */ } .storyline-split-main::-webkit-scrollbar { display: none; /* Chrome, Safari, Edge */ } .storyline-notes-resize { flex: 0 0 auto; height: 10px; margin: 0 -0.5rem; cursor: row-resize; background: linear-gradient(var(--bs-border-color), var(--bs-border-color)) center/2.5rem 2px no-repeat; border-top: 1px solid var(--bs-border-color); } .storyline-notes-resize:hover { background-color: var(--bs-tertiary-bg); } .storyline-notes-dock { flex: 0 0 var(--notes-h); min-height: 2.75rem; display: flex; flex-direction: column; background: var(--bs-body-bg); border-top: 1px solid var(--bs-border-color); } .storyline-notes-bar { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.4rem 0.1rem; } .storyline-notes-toggle { border: 0; background: none; padding: 0.15rem 0.25rem; font-weight: 600; color: var(--bs-body-color); display: inline-flex; align-items: center; gap: 0.4rem; cursor: pointer; } .storyline-notes-caret { transition: transform 0.15s ease; display: inline-block; } .storyline-notes-dock.is-collapsed { flex: 0 0 auto !important; } .storyline-notes-dock.is-collapsed .storyline-notes-body { display: none; } .storyline-notes-dock.is-collapsed .storyline-notes-caret { transform: rotate(-90deg); } .storyline-notes-resize:has(+ .storyline-notes-dock.is-collapsed) { display: none; } .storyline-notes-body { flex: 1 1 auto; min-height: 0; padding-bottom: 0.5rem; } .storyline-notes-form { height: 100%; display: flex; flex-direction: column; gap: 0.5rem; } .storyline-notes-text { flex: 1 1 auto; min-height: 0; resize: none; font-size: 0.95rem; line-height: 1.55; } .storyline-notes-actions { flex: 0 0 auto; display: flex; align-items: center; gap: 0.75rem; } /* Small or short screens: no fixed split, just stack notes under the chapter. */ @media (max-width: 767.98px), (max-height: 560px) { .storyline-chapter-page { overflow: visible; } .storyline-chapter-page main.app-main { height: auto; padding-top: 1.5rem; padding-bottom: 3rem; } .storyline-chapter-page main.app-main > .container { display: block; height: auto; } .storyline-split { display: block; } .storyline-split-main { overflow: visible; } .storyline-notes-resize { display: none; } .storyline-notes-dock { flex-basis: auto; margin-top: 1.5rem; border-top-width: 2px; padding-top: 0.5rem; } .storyline-notes-text { min-height: 9rem; } } /* Chapter list: kicker line above each title */ .storyline-chapter-kicker { display: block; text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.72rem; font-weight: 700; color: var(--bs-primary); } /* --- Storyline: session / adventure chapter components -------------- */ /* At-a-glance metadata band under the chapter header */ .storyline-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(12.5rem, 1fr)); gap: 0.6rem 1.75rem; margin: 0 0 2rem; padding: 1rem 1.25rem; background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); border-radius: 0.5rem; } .storyline-meta > div { display: flex; flex-direction: column; } .storyline-meta dt { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.07em; color: var(--bs-secondary-color); } .storyline-meta dd { margin: 0.1rem 0 0; font-weight: 500; } /* In-world handout / posted notice */ .storyline-handout { max-width: 24rem; margin: 1.75rem auto; padding: 1.5rem 1.75rem; text-align: center; background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); border-radius: 2px; box-shadow: 0 0 0 5px var(--bs-body-bg), 0 0 0 6px var(--bs-border-color); font-family: ui-monospace, "Cascadia Code", "Consolas", monospace; font-size: 0.95rem; line-height: 1.8; letter-spacing: 0.02em; } .storyline-handout strong { display: block; letter-spacing: 0.14em; text-transform: uppercase; margin-bottom: 0.6rem; } /* Label + body rows: skill checks, day prompts */ .storyline-rows { list-style: none; margin: 1.25rem 0; padding: 0; } .storyline-rows li { display: flex; gap: 1rem; padding: 0.55rem 0; border-top: 1px solid var(--bs-border-color); } .storyline-rows li:last-child { border-bottom: 1px solid var(--bs-border-color); } .storyline-rows .k { flex: 0 0 9rem; font-weight: 600; color: var(--bs-primary); font-variant-numeric: tabular-nums; } @media (max-width: 40rem) { .storyline-rows li { flex-direction: column; gap: 0.15rem; } .storyline-rows .k { flex-basis: auto; } } /* Question / answer + itemised lists */ .storyline-qa { margin: 1.25rem 0; } .storyline-qa > div { padding: 0.55rem 0; border-top: 1px solid var(--bs-border-color); } .storyline-qa > div:last-child { border-bottom: 1px solid var(--bs-border-color); } .storyline-qa dt { font-weight: 600; } .storyline-qa dd { margin: 0.15rem 0 0; color: var(--bs-secondary-color); } /* Staged encounter */ .storyline-stages { display: grid; gap: 0.75rem; margin: 1.25rem 0; } .storyline-stage { padding: 0.9rem 1.1rem; background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); border-left: 3px solid var(--bs-primary); border-radius: 0.4rem; } .storyline-stage h4 { font-size: 0.95rem; text-transform: uppercase; letter-spacing: 0.06em; margin: 0 0 0.4rem; } .storyline-stage > :last-child { margin-bottom: 0; } /* A dramatic beat: SCRATCH / sign text / milestone */ .storyline-beat { text-align: center; letter-spacing: 0.3em; text-transform: uppercase; font-weight: 700; font-size: 1.1rem; margin: 1.75rem 0 !important; } /* Before / after legend distortion */ .storyline-legend { list-style: none; margin: 1.25rem 0; padding: 0; display: grid; gap: 0.9rem; } .storyline-legend li { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 0.9rem; } .storyline-legend .from { text-align: right; font-style: italic; color: var(--bs-secondary-color); } .storyline-legend .arrow { color: var(--bs-primary); font-size: 1.1rem; } .storyline-legend .to { font-style: italic; } @media (max-width: 45rem) { .storyline-legend li { grid-template-columns: 1fr; gap: 0.2rem; } .storyline-legend .from { text-align: left; } .storyline-legend .arrow { display: none; } }