.tex-setup-modal { width: min(440px, calc(100vw - 40px)); max-height: min(85vh, 640px); overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain;}.tex-setup-modal > p { margin-bottom: var(--space-8); }.tex-setup-install { width: 100%; justify-content: center; gap: var(--space-3);}.modal-actions .tex-setup-install { width: auto; }.tex-setup-install .tex-setup-install-loader > img { filter: invert(1); opacity: 1;}.tex-setup-progress-block { display: grid; gap: var(--space-4); margin-bottom: var(--space-8);}.tex-setup-progress-copy { display: grid; gap: var(--space-2);}.tex-setup-progress-copy > span { color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height);}.tex-setup-progress-copy > small { color: var(--text-tertiary); font-size: var(--type-micro-size); line-height: var(--type-caption-line-height);}.tex-setup-progress { height: var(--space-3); overflow: hidden; border-radius: var(--radius-pill); background: var(--border-subtle);}.tex-setup-progress-fill { position: relative; height: 100%; overflow: hidden; border-radius: inherit; corner-shape: inherit; background: var(--control-active); transition: width var(--motion-slow);}.tex-setup-progress-fill::after { position: absolute; inset: 0; background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--surface-app) 35%, transparent), transparent); animation: tex-setup-progress-shimmer 1.4s linear infinite; content: ""; transform: translateX(-100%);}.tex-setup-status { margin: 0 0 var(--space-8); padding: var(--space-4) var(--space-5); border-radius: var(--radius-control); white-space: pre-wrap;}/* tlmgr's own words, folded under the plain-language summary. */.tex-setup-error-details { margin: calc(var(--space-6) * -1) 0 var(--space-8); color: var(--text-tertiary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height);}.tex-setup-error-details > summary { width: max-content; padding: var(--space-1) var(--space-3); border-radius: var(--radius-compact); display: flex; align-items: center; gap: var(--gap-tight); list-style: none; cursor: pointer; transition: color var(--motion-fast), background-color var(--motion-fast);}.tex-setup-error-details > summary::-webkit-details-marker { display: none; }.tex-setup-error-details > summary:hover { color: var(--text-secondary); background: var(--tone-hover-surface); }.tex-setup-error-details > summary > svg { transition: transform var(--motion-fast); }.tex-setup-error-details[open] > summary > svg { transform: rotate(90deg); }.tex-setup-error-details > pre { max-height: 132px; margin: var(--space-3) 0 0; padding: var(--space-4) var(--space-5); overflow: auto; border: 1px solid var(--border-subtle); border-radius: var(--radius-chrome); background: var(--surface-panel); color: var(--text-secondary); font-family: var(--editor-font); font-size: var(--type-micro-size); line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; user-select: text;}@keyframes tex-setup-progress-shimmer { to { transform: translateX(100%); }} .todo-drawer { width: min(460px, 100%); }/* Empty: the note spike on the drawer's own surface (trellis.css), a title, one line on where markers come from, then the markers themselves. */.todo-empty { --art-paper: var(--surface-input); padding: var(--space-10) var(--space-6); }.todo-empty .research-art { width: 144px; margin-bottom: var(--space-4); }.todo-empty .ui-empty-state-description { max-width: 34ch; color: var(--text-secondary); text-wrap: pretty; }.todo-empty .ui-empty-state-actions { margin-top: var(--space-4); }.todo-empty-markers { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-3); }.todo-empty-markers code { display: block; padding: var(--space-1) var(--space-4); border-radius: var(--radius-compact); box-shadow: 0 0 0 1px var(--border-subtle); background: var(--surface-panel-raised); color: var(--text-secondary); font-family: var(--editor-font); font-size: var(--type-micro-size); line-height: var(--type-caption-line-height); white-space: nowrap; }/* With markers: a count, then each file's markers under its name, as Find groups its hits. A row is the kind as the writer typed it, the line, and the comment itself; FIXME and XXX take the danger tone, as flagged work. */.todo-summary { margin: 0 0 var(--space-4); display: flex; flex-wrap: wrap; gap: 0 var(--space-3); color: var(--text-primary); font-size: var(--type-subtitle-size); line-height: var(--type-subtitle-line-height); font-weight: var(--type-subtitle-weight); font-variant-numeric: tabular-nums; }.todo-summary span { color: var(--text-secondary); font-weight: var(--weight-regular); }/* Rows reach into the drawer's inset so their text lines up with the count. */.todo-hits { --nested-radius: var(--radius-control); margin: 0 calc(-1 * var(--space-5)); display: grid; gap: var(--space-6); }.todo-file { min-width: 0; }.todo-file-head { min-width: 0; margin: 0 0 var(--space-2); padding: 0 var(--space-5); display: flex; align-items: center; gap: var(--space-3); color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-weight: var(--weight-medium); }.todo-file-head svg { flex: none; color: var(--text-tertiary); }.todo-file-path { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }.todo-file-count { flex: none; margin-left: auto; color: var(--text-tertiary); font-variant-numeric: tabular-nums; }.todo-file-hits { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-1); }.todo-hit { position: relative; width: 100%; padding: var(--space-4) var(--space-5); border: 0; border-radius: var(--radius-control); background: transparent; color: inherit; font: inherit; text-align: left; display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: baseline; gap: var(--space-2) var(--space-4); cursor: pointer;}.todo-hit:hover { background: var(--control-hover-surface); }.todo-hit-kind { padding: 0 var(--space-3); border-radius: var(--radius-compact); background: var(--control-active-soft); color: var(--control-active); font-family: var(--editor-font); font-size: var(--type-micro-size); line-height: var(--type-caption-line-height); font-weight: var(--weight-semibold); white-space: nowrap; }.todo-hit:is([data-kind="fixme"], [data-kind="xxx"]) .todo-hit-kind { background: var(--status-danger-soft); color: var(--status-danger); }.todo-hit-path { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }.todo-hit-line { justify-self: end; color: var(--text-tertiary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-variant-numeric: tabular-nums; }.todo-hit-preview { grid-column: 1 / -1; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; color: var(--text-primary); font-family: var(--editor-font); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); }.checklist-drawer { width: min(420px, 100%); }/* The verdict first, in the title serif: whether anything stands between the manuscript and submission. The track below it gives each check one segment in the order of the rows, so a glance finds which ones are holding it. */.checklist-summary { margin-bottom: var(--space-6); padding: var(--space-6) var(--space-6) var(--space-5); border-radius: var(--radius-panel); background: var(--surface-panel-raised); box-shadow: 0 0 0 1px var(--border-subtle);}.checklist-verdict { margin: 0; color: var(--text-primary); font-family: var(--type-title-font); font-size: var(--type-title-size); line-height: var(--type-title-line-height); font-weight: var(--type-title-weight); text-wrap: balance; }.checklist-progress { margin-top: var(--space-4); display: flex; align-items: center; gap: var(--space-4); }.checklist-progress-count { flex: none; color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-variant-numeric: tabular-nums; }.checklist-track { flex: 1; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--space-1); height: 4px; }.checklist-track > span { border-radius: var(--radius-pill); background: var(--border-strong); }.checklist-track > [data-state="ok"] { background: var(--status-success); }.checklist-track > [data-state="warn"] { background: var(--status-warning); }/* The deadline sits above the verdict on the same raised plate. Its urgency tints only the clock (grey, then amber under three days, then red), and the countdown itself turns red once a day is left, so the panel never shouts while there is time. */.deadline-card { margin-bottom: var(--space-4); padding: var(--space-5) var(--space-6) var(--space-6); border-radius: var(--radius-panel); background: var(--surface-panel-raised); box-shadow: 0 0 0 1px var(--border-subtle); display: grid; gap: var(--space-1);}.deadline-card-head { min-width: 0; display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); }/* A long venue name gives way with an ellipsis; the edit button keeps its place. */.deadline-card-venue { min-width: 0; display: inline-flex; align-items: center; gap: var(--space-3); color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-weight: var(--weight-medium); }.deadline-card-venue > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }.deadline-card-venue svg { flex: none; color: var(--text-tertiary); }.deadline-card[data-urgency="soon"] .deadline-card-venue svg { color: var(--status-warning); }.deadline-card[data-urgency="urgent"] .deadline-card-venue svg { color: var(--status-danger); }.deadline-card-left { margin: 0; word-break: keep-all; overflow-wrap: anywhere; color: var(--text-primary); font-family: var(--type-title-font); font-size: var(--type-title-size); line-height: var(--type-title-line-height); font-weight: var(--type-title-weight); font-variant-numeric: tabular-nums; text-wrap: balance; }.deadline-card[data-urgency="urgent"] .deadline-card-left { color: var(--status-danger); }.deadline-card-when { margin: var(--space-2) 0 0; color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-variant-numeric: tabular-nums; }.deadline-card-when b { color: var(--text-primary); font-weight: var(--weight-medium); }.deadline-card-local { min-height: var(--type-caption-line-height); margin: 0; color: var(--text-tertiary); font-size: var(--type-micro-size); line-height: var(--type-caption-line-height); font-variant-numeric: tabular-nums; }/* Without a deadline, one quiet line in the card's place offers to add it. */.deadline-add { width: 100%; margin-bottom: var(--space-4); padding: var(--space-5) var(--space-6); border: 1px dashed var(--border-strong); border-radius: var(--radius-panel); background: transparent; color: var(--text-secondary); display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: var(--space-4); text-align: left; font: inherit; cursor: pointer; transition: background-color var(--motion-fast);}.deadline-add:hover { background: var(--control-hover-surface); }.deadline-add svg { position: relative; top: 3px; }.deadline-add span { display: grid; gap: var(--space-1); }.deadline-add b { color: var(--text-primary); font-size: var(--type-body-size); line-height: var(--type-body-line-height); font-weight: var(--weight-medium); }/* One column that never grows past the card: the date input and the segmented control would otherwise hold it at their intrinsic width in a narrow drawer. */.deadline-form { grid-template-columns: minmax(0, 1fr); gap: var(--space-5); }.deadline-form .ui-segmented { min-width: 0; }.deadline-form .ui-segmented-tab { flex: 1 1 auto; padding-inline: var(--space-3); white-space: nowrap; }.deadline-form label { min-width: 0; display: grid; gap: var(--space-2); color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-weight: var(--weight-medium); }/* Date and time side by side when there is room, stacked in a narrow panel. */.deadline-form-when { display: flex; flex-wrap: wrap; gap: var(--space-4); }.deadline-form-when label { flex: 1 1 120px; }.deadline-form-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--space-3); }.deadline-form-remove { margin-inline-end: auto; }/* One grouped list, divided by hairlines, rather than a stack of outlined cards. Each row leads with its result as a mark; the values stay in ink, so colour is the mark's alone and never the only carrier of a result. */.checklist-rows { margin-bottom: var(--space-8); border: 1px solid var(--border-subtle); border-radius: var(--radius-panel); background: var(--surface-panel-raised); overflow: hidden; display: grid; container: checklist-rows / inline-size;}.checklist-row { display: grid; /* The label keeps its words whole and the value gives way first, wrapping at its " / ", so a narrow panel or a large budget never breaks a label letter by letter. */ grid-template-columns: 18px minmax(min-content, 1fr) auto; align-items: center; gap: var(--space-1) var(--space-5); padding: var(--space-5) var(--space-6); border: 0; background: transparent; color: inherit; text-align: left; font: inherit;}.checklist-row + .checklist-row { border-top: 1px solid var(--border-subtle); }button.checklist-row { cursor: pointer; transition: background-color var(--motion-fast); }button.checklist-row:hover { background: var(--control-hover-surface); }/* On the label's first line, centred on its 20px leading, even when the label wraps. */.checklist-status { align-self: start; position: relative; top: 1px; width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center; background: var(--border-subtle); color: var(--text-secondary); }.checklist-status svg { stroke-width: 2.25; }.checklist-row.ok .checklist-status { background: var(--status-success-soft); color: var(--status-success); }.checklist-row.warn .checklist-status { background: var(--status-warning-soft); color: var(--status-warning); }.checklist-row strong { font-size: var(--type-body-size); line-height: var(--type-body-line-height); font-weight: var(--weight-medium); word-break: keep-all; overflow-wrap: break-word; }.checklist-row span { display: inline-flex; align-items: center; gap: var(--space-2); justify-self: end; text-align: end; color: var(--text-primary); font-size: var(--type-body-size); line-height: var(--type-body-line-height); font-weight: var(--weight-medium); font-variant-numeric: tabular-nums; }.checklist-row span svg { color: var(--text-secondary); }/* Too narrow for a label and its value side by side (a tool panel at its minimum width, or a large budget): the value drops under its label. */@container checklist-rows (width < 240px) { .checklist-row { grid-template-columns: 18px minmax(0, 1fr); } .checklist-row > span { grid-column: 2; justify-self: start; text-align: start; }}.checklist-row small { grid-column: 2 / -1; color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); }/* A quiet hairline gauge under the label: the fill takes the row's result colour at reduced strength, and an overshoot past the limit mark reads in the full warning the row's mark carries. */.checklist-row .checklist-meter { --meter-tone: var(--text-secondary); grid-column: 2 / -1; justify-self: stretch; position: relative; display: block; height: 4px; margin-block: var(--space-3) var(--space-1); border-radius: var(--radius-pill); background: var(--border-subtle); overflow: hidden;}.checklist-row.ok .checklist-meter { --meter-tone: var(--status-success); }.checklist-row.warn .checklist-meter { --meter-tone: var(--status-warning); }.checklist-row .checklist-meter > span { position: absolute; inset-block: 0; left: 0; display: block; }.checklist-row .checklist-meter-fill { border-radius: inherit; corner-shape: inherit; background: color-mix(in srgb, var(--meter-tone) 56%, transparent); }/* Over the limit, the allowance itself is not the problem: it greys out and only the excess, past a notch at the limit, carries the warning. */.checklist-row .checklist-meter.over .checklist-meter-fill { border-radius: var(--radius-pill) 0 0 var(--radius-pill); background: color-mix(in srgb, var(--text-secondary) 42%, transparent); }.checklist-row .checklist-meter-over { background: var(--meter-tone); }.checklist-row .checklist-meter-over:not(:first-child) { border-left: 2px solid var(--surface-panel-raised); }.checklist-row small b { color: var(--text-primary); font-weight: var(--weight-semibold); }/* The figure inventory leads elsewhere rather than passing or failing, so its mark stays the neutral disc and its row reads as a way in, like TODOs. */.checklist-link .checklist-status svg { stroke-width: 2; }/* The double-blind and font checks, headed like the writer's items. Each finding is a line under its row: where it is (a way to it) and what it says, cut to one line, since the source line is the place to read it whole. */.checklist-review h3 { margin: 0 0 var(--space-3); color: var(--text-primary); font-size: var(--type-subtitle-size); line-height: var(--type-subtitle-line-height); font-weight: var(--type-subtitle-weight); word-break: keep-all; overflow-wrap: break-word; }.checklist-review p { margin: 0 0 var(--space-8); color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); }.checklist-findings { grid-column: 2 / -1; min-width: 0; margin: var(--space-1) 0 0; padding: 0; list-style: none; display: grid; gap: var(--space-1); }.checklist-findings li { min-width: 0; display: flex; align-items: baseline; gap: var(--space-3); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); }.checklist-findings button { flex: none; max-width: 60%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0; border: 0; background: transparent; color: var(--control-active); font: inherit; font-variant-numeric: tabular-nums; cursor: pointer; }.checklist-findings button:hover { text-decoration: underline; text-underline-offset: 3px; }.checklist-findings .checklist-finding-text { display: block; min-width: 0; justify-self: auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: start; color: var(--text-secondary); font-size: inherit; line-height: inherit; font-weight: var(--weight-regular); font-variant-numeric: normal; }/* The limits close the panel as a section of their own, headed like the writer's items above, so the fields never read as part of either list. */.checklist-limits h3 { margin: 0 0 var(--space-3); color: var(--text-primary); font-size: var(--type-subtitle-size); line-height: var(--type-subtitle-line-height); font-weight: var(--type-subtitle-weight); word-break: keep-all; overflow-wrap: break-word; }/* One row when the drawer has room; in a narrow one the button wraps to a row of its own rather than squeezing the two fields down to an ellipsis. */.checklist-budgets { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: end;}.checklist-budgets label { flex: 3 1 88px; min-width: 0; display: grid; gap: var(--space-2); color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-weight: var(--weight-medium);}.checklist-budgets input { height: var(--control-height-default); border-color: var(--field-control-border-color); border-radius: var(--field-control-radius); padding: 0 var(--space-4); background: var(--field-control-background); color: var(--text-primary); font-size: var(--type-body-compact-size);}.checklist-budgets button { /* A field's basis, so it never pairs up with a lone field. */ flex: 1 0 88px; height: var(--control-height-default); border: 1px solid var(--control-active-border); border-radius: var(--radius-icon); padding: 0 var(--space-6); background: var(--control-active-soft); color: var(--control-active); font-size: var(--type-body-compact-size); font-weight: var(--type-body-compact-weight);} /* The writer's own items: the same hairline list as the automatic checks, the mark a button that ticks the item, the title a button that opens its fields in place. A file gone or changed since sign-off takes the warning mark. */.submission-items { margin-bottom: var(--space-8); }.submission-items .checklist-rows { margin-bottom: 0; }.submission-items-head { min-width: 0; display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-3); }/* The title and its count wrap as words beside the template button, never letter by letter. */.submission-items-title { min-width: 0; flex: 1 1 auto; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--space-3); }.submission-items-head h3 { margin: 0; min-width: 0; word-break: keep-all; overflow-wrap: break-word; color: var(--text-primary); font-size: var(--type-subtitle-size); line-height: var(--type-subtitle-line-height); font-weight: var(--type-subtitle-weight); }.submission-items-title > span { color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-variant-numeric: tabular-nums; white-space: nowrap; }.submission-items-head > :last-child { flex: none; align-self: start; }.submission-template-form { margin-bottom: var(--space-4); }.submission-template-menu [data-slot="dropdown-menu-item"] { gap: var(--space-4); }.submission-template-name { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }.submission-template-count { color: var(--text-tertiary); font-variant-numeric: tabular-nums; }.submission-rows > * + * { border-top: 1px solid var(--border-subtle); }.checklist-row.submission-row { grid-template-columns: 18px minmax(0, 1fr); }.submission-row span { display: inline; justify-self: auto; text-align: inherit; color: inherit; font: inherit; }.submission-toggle { align-self: start; width: 18px; height: 18px; padding: 0; border: 0; border-radius: 50%; background: transparent; cursor: pointer;}.submission-toggle .checklist-status { top: 0; transition: box-shadow var(--motion-fast); }.submission-toggle:hover .checklist-status { box-shadow: 0 0 0 1px var(--border-strong); }.submission-title { min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: var(--space-1) var(--space-5); padding: 0; border: 0; background: transparent; color: inherit; text-align: start; font: inherit; cursor: pointer;}.submission-title:hover strong { text-decoration: underline; text-decoration-color: var(--border-strong); text-underline-offset: 3px; }.submission-title strong { overflow-wrap: anywhere; }.submission-row .submission-state { color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); white-space: nowrap; }.submission-row.warn .submission-state { color: var(--status-warning); font-weight: var(--weight-medium); }/* A narrow drawer puts the state under the title rather than squeezing either. */@container checklist-rows (width < 360px) { .submission-title { grid-template-columns: minmax(0, 1fr); } .submission-row .submission-state { white-space: normal; }}.submission-row .submission-meta { min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-4); }.submission-meta > * { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }.submission-row .submission-owner { color: var(--text-primary); font-weight: var(--weight-medium); }.submission-chip { display: inline-flex; align-items: center; gap: var(--space-1); padding: 0; border: 0; background: transparent; color: var(--control-active); font: inherit; cursor: pointer;}.submission-chip > span { overflow: hidden; text-overflow: ellipsis; }.submission-chip svg { flex: none; }.submission-chip:hover > span { text-decoration: underline; text-underline-offset: 2px; }.submission-row.warn[data-condition="missing"] .submission-chip { color: var(--text-secondary); text-decoration: line-through; }.submission-form { padding: var(--space-5) var(--space-6) var(--space-6); display: grid; }.submission-add { display: grid; grid-template-columns: 18px minmax(0, 1fr); align-items: center; gap: var(--space-5); padding: var(--space-4) var(--space-6); color: var(--text-tertiary); }.submission-add svg { justify-self: center; }.submission-add input { min-width: 0; height: var(--control-height-compact); padding: 0; border: 0; outline: none; background: transparent; color: var(--text-primary); font-size: var(--type-body-size); line-height: var(--type-body-line-height); }.submission-add input::placeholder { color: var(--text-tertiary); }.submission-add:focus-within { background: var(--control-hover-surface); } .welcome-screen { width: 100%; height: 100%; background: var(--surface-backdrop); position: relative; overflow: hidden; }.welcome-titlebar { position: absolute; z-index: 3; top: 0; left: 0; right: 0; height: 48px; display: flex; justify-content: flex-end; align-items: center; padding: 0 14px; }.welcome-content { position: relative; z-index: 1; width: min(520px, calc(100% - 48px)); height: 100%; margin: auto; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding-bottom: var(--space-10); }.brand-mark { width: 50px; height: 50px; border-radius: 14px; display: grid; place-items: center; color: var(--control-active); }/* The one brand moment: the mark, then a serif title at a size that greets rather than advertises. Chinese takes Songti SC through --display-font, a serif like the Latin; it sets solid, so it opens its tracking a little where the Latin tightens. */.welcome-content h1 { margin: var(--space-10) 0 0; font-family: var(--display-font); font-size: clamp(36px, 4.4vw, 48px); line-height: 1.08; font-weight: 400; letter-spacing: -.02em; text-wrap: balance; } /* Only the welcome composition enters; busy updates and project contents do not. */.welcome-content > :not(.busy-label) { animation: welcome-rise var(--motion-slow) both; }.welcome-content > .welcome-actions,.welcome-content > .welcome-more,.welcome-content > .welcome-recents { animation-delay: 60ms; }@keyframes welcome-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); }}.welcome-actions { margin-top: var(--space-12); display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-4); } /* The other ways in, last: quieter than the actions and the recent projects above them, and on one line at the width the content column actually has. */.welcome-more { margin-top: var(--space-8); display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: var(--space-2);}.welcome-more-action { height: var(--control-height-compact); padding: 0 var(--pad-inline-control); border-radius: var(--radius-chrome); background: transparent; color: var(--text-secondary); display: inline-flex; align-items: center; gap: var(--space-3); font-size: var(--type-caption-size); font-weight: var(--weight-regular); white-space: nowrap;}.welcome-more-action:hover { background: var(--border-subtle); color: var(--text-primary); }/* The projects to go back to, and why the last one did not open: the writer's way back, so it comes straight after the actions. Wider than the column above it, so three pages read at a size where a title shows. */.welcome-recents { width: min(720px, calc(100vw - 64px)); margin-top: var(--space-16); display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); text-align: start; }.welcome-unopened { padding-inline: var(--space-1); }.welcome-recents-title { margin: 0; padding-inline: var(--space-1); color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-weight: var(--weight-medium); }/* The desk: each project as the first page of its paper, paper-coloured in both themes as the PDF preview draws it, its name in the title serif under it. Cards keep a third of the width however many there are; fewer than three shrink the desk around them, so the title stays at its start. */.welcome-desk-frame { --desk-count: 3; width: calc((100% + var(--space-8)) * var(--desk-count) / 3 - var(--space-8)); justify-self: center; display: grid; gap: var(--space-4); }.welcome-desk { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(var(--desk-count), minmax(0, 1fr)); gap: var(--space-8); }.welcome-desk-card { width: 100%; padding: 0; border: 0; border-radius: calc(var(--radius-panel) * var(--corner-smoothing)); corner-shape: squircle; background: transparent; color: var(--text-secondary); display: grid; grid-template-columns: minmax(0, 1fr); text-align: start;Lines 1–500 of 1181. Load more
.tex-setup-modal { width: min(440px, calc(100vw - 40px)); max-height: min(85vh, 640px); overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; } .tex-setup-modal > p { margin-bottom: var(--space-8); } .tex-setup-install { width: 100%; justify-content: center; gap: var(--space-3); } .modal-actions .tex-setup-install { width: auto; } .tex-setup-install .tex-setup-install-loader > img { filter: invert(1); opacity: 1; } .tex-setup-progress-block { display: grid; gap: var(--space-4); margin-bottom: var(--space-8); } .tex-setup-progress-copy { display: grid; gap: var(--space-2); } .tex-setup-progress-copy > span { color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); } .tex-setup-progress-copy > small { color: var(--text-tertiary); font-size: var(--type-micro-size); line-height: var(--type-caption-line-height); } .tex-setup-progress { height: var(--space-3); overflow: hidden; border-radius: var(--radius-pill); background: var(--border-subtle); } .tex-setup-progress-fill { position: relative; height: 100%; overflow: hidden; border-radius: inherit; corner-shape: inherit; background: var(--control-active); transition: width var(--motion-slow); } .tex-setup-progress-fill::after { position: absolute; inset: 0; background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--surface-app) 35%, transparent), transparent); animation: tex-setup-progress-shimmer 1.4s linear infinite; content: ""; transform: translateX(-100%); } .tex-setup-status { margin: 0 0 var(--space-8); padding: var(--space-4) var(--space-5); border-radius: var(--radius-control); white-space: pre-wrap; } /* tlmgr's own words, folded under the plain-language summary. */ .tex-setup-error-details { margin: calc(var(--space-6) * -1) 0 var(--space-8); color: var(--text-tertiary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); } .tex-setup-error-details > summary { width: max-content; padding: var(--space-1) var(--space-3); border-radius: var(--radius-compact); display: flex; align-items: center; gap: var(--gap-tight); list-style: none; cursor: pointer; transition: color var(--motion-fast), background-color var(--motion-fast); } .tex-setup-error-details > summary::-webkit-details-marker { display: none; } .tex-setup-error-details > summary:hover { color: var(--text-secondary); background: var(--tone-hover-surface); } .tex-setup-error-details > summary > svg { transition: transform var(--motion-fast); } .tex-setup-error-details[open] > summary > svg { transform: rotate(90deg); } .tex-setup-error-details > pre { max-height: 132px; margin: var(--space-3) 0 0; padding: var(--space-4) var(--space-5); overflow: auto; border: 1px solid var(--border-subtle); border-radius: var(--radius-chrome); background: var(--surface-panel); color: var(--text-secondary); font-family: var(--editor-font); font-size: var(--type-micro-size); line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; user-select: text; } @keyframes tex-setup-progress-shimmer { to { transform: translateX(100%); } } .todo-drawer { width: min(460px, 100%); } /* Empty: the note spike on the drawer's own surface (trellis.css), a title, one line on where markers come from, then the markers themselves. */ .todo-empty { --art-paper: var(--surface-input); padding: var(--space-10) var(--space-6); } .todo-empty .research-art { width: 144px; margin-bottom: var(--space-4); } .todo-empty .ui-empty-state-description { max-width: 34ch; color: var(--text-secondary); text-wrap: pretty; } .todo-empty .ui-empty-state-actions { margin-top: var(--space-4); } .todo-empty-markers { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-3); } .todo-empty-markers code { display: block; padding: var(--space-1) var(--space-4); border-radius: var(--radius-compact); box-shadow: 0 0 0 1px var(--border-subtle); background: var(--surface-panel-raised); color: var(--text-secondary); font-family: var(--editor-font); font-size: var(--type-micro-size); line-height: var(--type-caption-line-height); white-space: nowrap; } /* With markers: a count, then each file's markers under its name, as Find groups its hits. A row is the kind as the writer typed it, the line, and the comment itself; FIXME and XXX take the danger tone, as flagged work. */ .todo-summary { margin: 0 0 var(--space-4); display: flex; flex-wrap: wrap; gap: 0 var(--space-3); color: var(--text-primary); font-size: var(--type-subtitle-size); line-height: var(--type-subtitle-line-height); font-weight: var(--type-subtitle-weight); font-variant-numeric: tabular-nums; } .todo-summary span { color: var(--text-secondary); font-weight: var(--weight-regular); } /* Rows reach into the drawer's inset so their text lines up with the count. */ .todo-hits { --nested-radius: var(--radius-control); margin: 0 calc(-1 * var(--space-5)); display: grid; gap: var(--space-6); } .todo-file { min-width: 0; } .todo-file-head { min-width: 0; margin: 0 0 var(--space-2); padding: 0 var(--space-5); display: flex; align-items: center; gap: var(--space-3); color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-weight: var(--weight-medium); } .todo-file-head svg { flex: none; color: var(--text-tertiary); } .todo-file-path { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .todo-file-count { flex: none; margin-left: auto; color: var(--text-tertiary); font-variant-numeric: tabular-nums; } .todo-file-hits { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-1); } .todo-hit { position: relative; width: 100%; padding: var(--space-4) var(--space-5); border: 0; border-radius: var(--radius-control); background: transparent; color: inherit; font: inherit; text-align: left; display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: baseline; gap: var(--space-2) var(--space-4); cursor: pointer; } .todo-hit:hover { background: var(--control-hover-surface); } .todo-hit-kind { padding: 0 var(--space-3); border-radius: var(--radius-compact); background: var(--control-active-soft); color: var(--control-active); font-family: var(--editor-font); font-size: var(--type-micro-size); line-height: var(--type-caption-line-height); font-weight: var(--weight-semibold); white-space: nowrap; } .todo-hit:is([data-kind="fixme"], [data-kind="xxx"]) .todo-hit-kind { background: var(--status-danger-soft); color: var(--status-danger); } .todo-hit-path { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } .todo-hit-line { justify-self: end; color: var(--text-tertiary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-variant-numeric: tabular-nums; } .todo-hit-preview { grid-column: 1 / -1; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; color: var(--text-primary); font-family: var(--editor-font); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); } .checklist-drawer { width: min(420px, 100%); } /* The verdict first, in the title serif: whether anything stands between the manuscript and submission. The track below it gives each check one segment in the order of the rows, so a glance finds which ones are holding it. */ .checklist-summary { margin-bottom: var(--space-6); padding: var(--space-6) var(--space-6) var(--space-5); border-radius: var(--radius-panel); background: var(--surface-panel-raised); box-shadow: 0 0 0 1px var(--border-subtle); } .checklist-verdict { margin: 0; color: var(--text-primary); font-family: var(--type-title-font); font-size: var(--type-title-size); line-height: var(--type-title-line-height); font-weight: var(--type-title-weight); text-wrap: balance; } .checklist-progress { margin-top: var(--space-4); display: flex; align-items: center; gap: var(--space-4); } .checklist-progress-count { flex: none; color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-variant-numeric: tabular-nums; } .checklist-track { flex: 1; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--space-1); height: 4px; } .checklist-track > span { border-radius: var(--radius-pill); background: var(--border-strong); } .checklist-track > [data-state="ok"] { background: var(--status-success); } .checklist-track > [data-state="warn"] { background: var(--status-warning); } /* The deadline sits above the verdict on the same raised plate. Its urgency tints only the clock (grey, then amber under three days, then red), and the countdown itself turns red once a day is left, so the panel never shouts while there is time. */ .deadline-card { margin-bottom: var(--space-4); padding: var(--space-5) var(--space-6) var(--space-6); border-radius: var(--radius-panel); background: var(--surface-panel-raised); box-shadow: 0 0 0 1px var(--border-subtle); display: grid; gap: var(--space-1); } .deadline-card-head { min-width: 0; display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); } /* A long venue name gives way with an ellipsis; the edit button keeps its place. */ .deadline-card-venue { min-width: 0; display: inline-flex; align-items: center; gap: var(--space-3); color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-weight: var(--weight-medium); } .deadline-card-venue > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .deadline-card-venue svg { flex: none; color: var(--text-tertiary); } .deadline-card[data-urgency="soon"] .deadline-card-venue svg { color: var(--status-warning); } .deadline-card[data-urgency="urgent"] .deadline-card-venue svg { color: var(--status-danger); } .deadline-card-left { margin: 0; word-break: keep-all; overflow-wrap: anywhere; color: var(--text-primary); font-family: var(--type-title-font); font-size: var(--type-title-size); line-height: var(--type-title-line-height); font-weight: var(--type-title-weight); font-variant-numeric: tabular-nums; text-wrap: balance; } .deadline-card[data-urgency="urgent"] .deadline-card-left { color: var(--status-danger); } .deadline-card-when { margin: var(--space-2) 0 0; color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-variant-numeric: tabular-nums; } .deadline-card-when b { color: var(--text-primary); font-weight: var(--weight-medium); } .deadline-card-local { min-height: var(--type-caption-line-height); margin: 0; color: var(--text-tertiary); font-size: var(--type-micro-size); line-height: var(--type-caption-line-height); font-variant-numeric: tabular-nums; } /* Without a deadline, one quiet line in the card's place offers to add it. */ .deadline-add { width: 100%; margin-bottom: var(--space-4); padding: var(--space-5) var(--space-6); border: 1px dashed var(--border-strong); border-radius: var(--radius-panel); background: transparent; color: var(--text-secondary); display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: var(--space-4); text-align: left; font: inherit; cursor: pointer; transition: background-color var(--motion-fast); } .deadline-add:hover { background: var(--control-hover-surface); } .deadline-add svg { position: relative; top: 3px; } .deadline-add span { display: grid; gap: var(--space-1); } .deadline-add b { color: var(--text-primary); font-size: var(--type-body-size); line-height: var(--type-body-line-height); font-weight: var(--weight-medium); } /* One column that never grows past the card: the date input and the segmented control would otherwise hold it at their intrinsic width in a narrow drawer. */ .deadline-form { grid-template-columns: minmax(0, 1fr); gap: var(--space-5); } .deadline-form .ui-segmented { min-width: 0; } .deadline-form .ui-segmented-tab { flex: 1 1 auto; padding-inline: var(--space-3); white-space: nowrap; } .deadline-form label { min-width: 0; display: grid; gap: var(--space-2); color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-weight: var(--weight-medium); } /* Date and time side by side when there is room, stacked in a narrow panel. */ .deadline-form-when { display: flex; flex-wrap: wrap; gap: var(--space-4); } .deadline-form-when label { flex: 1 1 120px; } .deadline-form-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--space-3); } .deadline-form-remove { margin-inline-end: auto; } /* One grouped list, divided by hairlines, rather than a stack of outlined cards. Each row leads with its result as a mark; the values stay in ink, so colour is the mark's alone and never the only carrier of a result. */ .checklist-rows { margin-bottom: var(--space-8); border: 1px solid var(--border-subtle); border-radius: var(--radius-panel); background: var(--surface-panel-raised); overflow: hidden; display: grid; container: checklist-rows / inline-size; } .checklist-row { display: grid; /* The label keeps its words whole and the value gives way first, wrapping at its " / ", so a narrow panel or a large budget never breaks a label letter by letter. */ grid-template-columns: 18px minmax(min-content, 1fr) auto; align-items: center; gap: var(--space-1) var(--space-5); padding: var(--space-5) var(--space-6); border: 0; background: transparent; color: inherit; text-align: left; font: inherit; } .checklist-row + .checklist-row { border-top: 1px solid var(--border-subtle); } button.checklist-row { cursor: pointer; transition: background-color var(--motion-fast); } button.checklist-row:hover { background: var(--control-hover-surface); } /* On the label's first line, centred on its 20px leading, even when the label wraps. */ .checklist-status { align-self: start; position: relative; top: 1px; width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center; background: var(--border-subtle); color: var(--text-secondary); } .checklist-status svg { stroke-width: 2.25; } .checklist-row.ok .checklist-status { background: var(--status-success-soft); color: var(--status-success); } .checklist-row.warn .checklist-status { background: var(--status-warning-soft); color: var(--status-warning); } .checklist-row strong { font-size: var(--type-body-size); line-height: var(--type-body-line-height); font-weight: var(--weight-medium); word-break: keep-all; overflow-wrap: break-word; } .checklist-row span { display: inline-flex; align-items: center; gap: var(--space-2); justify-self: end; text-align: end; color: var(--text-primary); font-size: var(--type-body-size); line-height: var(--type-body-line-height); font-weight: var(--weight-medium); font-variant-numeric: tabular-nums; } .checklist-row span svg { color: var(--text-secondary); } /* Too narrow for a label and its value side by side (a tool panel at its minimum width, or a large budget): the value drops under its label. */ @container checklist-rows (width < 240px) { .checklist-row { grid-template-columns: 18px minmax(0, 1fr); } .checklist-row > span { grid-column: 2; justify-self: start; text-align: start; } } .checklist-row small { grid-column: 2 / -1; color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); } /* A quiet hairline gauge under the label: the fill takes the row's result colour at reduced strength, and an overshoot past the limit mark reads in the full warning the row's mark carries. */ .checklist-row .checklist-meter { --meter-tone: var(--text-secondary); grid-column: 2 / -1; justify-self: stretch; position: relative; display: block; height: 4px; margin-block: var(--space-3) var(--space-1); border-radius: var(--radius-pill); background: var(--border-subtle); overflow: hidden; } .checklist-row.ok .checklist-meter { --meter-tone: var(--status-success); } .checklist-row.warn .checklist-meter { --meter-tone: var(--status-warning); } .checklist-row .checklist-meter > span { position: absolute; inset-block: 0; left: 0; display: block; } .checklist-row .checklist-meter-fill { border-radius: inherit; corner-shape: inherit; background: color-mix(in srgb, var(--meter-tone) 56%, transparent); } /* Over the limit, the allowance itself is not the problem: it greys out and only the excess, past a notch at the limit, carries the warning. */ .checklist-row .checklist-meter.over .checklist-meter-fill { border-radius: var(--radius-pill) 0 0 var(--radius-pill); background: color-mix(in srgb, var(--text-secondary) 42%, transparent); } .checklist-row .checklist-meter-over { background: var(--meter-tone); } .checklist-row .checklist-meter-over:not(:first-child) { border-left: 2px solid var(--surface-panel-raised); } .checklist-row small b { color: var(--text-primary); font-weight: var(--weight-semibold); } /* The figure inventory leads elsewhere rather than passing or failing, so its mark stays the neutral disc and its row reads as a way in, like TODOs. */ .checklist-link .checklist-status svg { stroke-width: 2; } /* The double-blind and font checks, headed like the writer's items. Each finding is a line under its row: where it is (a way to it) and what it says, cut to one line, since the source line is the place to read it whole. */ .checklist-review h3 { margin: 0 0 var(--space-3); color: var(--text-primary); font-size: var(--type-subtitle-size); line-height: var(--type-subtitle-line-height); font-weight: var(--type-subtitle-weight); word-break: keep-all; overflow-wrap: break-word; } .checklist-review p { margin: 0 0 var(--space-8); color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); } .checklist-findings { grid-column: 2 / -1; min-width: 0; margin: var(--space-1) 0 0; padding: 0; list-style: none; display: grid; gap: var(--space-1); } .checklist-findings li { min-width: 0; display: flex; align-items: baseline; gap: var(--space-3); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); } .checklist-findings button { flex: none; max-width: 60%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0; border: 0; background: transparent; color: var(--control-active); font: inherit; font-variant-numeric: tabular-nums; cursor: pointer; } .checklist-findings button:hover { text-decoration: underline; text-underline-offset: 3px; } .checklist-findings .checklist-finding-text { display: block; min-width: 0; justify-self: auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: start; color: var(--text-secondary); font-size: inherit; line-height: inherit; font-weight: var(--weight-regular); font-variant-numeric: normal; } /* The limits close the panel as a section of their own, headed like the writer's items above, so the fields never read as part of either list. */ .checklist-limits h3 { margin: 0 0 var(--space-3); color: var(--text-primary); font-size: var(--type-subtitle-size); line-height: var(--type-subtitle-line-height); font-weight: var(--type-subtitle-weight); word-break: keep-all; overflow-wrap: break-word; } /* One row when the drawer has room; in a narrow one the button wraps to a row of its own rather than squeezing the two fields down to an ellipsis. */ .checklist-budgets { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: end; } .checklist-budgets label { flex: 3 1 88px; min-width: 0; display: grid; gap: var(--space-2); color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-weight: var(--weight-medium); } .checklist-budgets input { height: var(--control-height-default); border-color: var(--field-control-border-color); border-radius: var(--field-control-radius); padding: 0 var(--space-4); background: var(--field-control-background); color: var(--text-primary); font-size: var(--type-body-compact-size); } .checklist-budgets button { /* A field's basis, so it never pairs up with a lone field. */ flex: 1 0 88px; height: var(--control-height-default); border: 1px solid var(--control-active-border); border-radius: var(--radius-icon); padding: 0 var(--space-6); background: var(--control-active-soft); color: var(--control-active); font-size: var(--type-body-compact-size); font-weight: var(--type-body-compact-weight); } /* The writer's own items: the same hairline list as the automatic checks, the mark a button that ticks the item, the title a button that opens its fields in place. A file gone or changed since sign-off takes the warning mark. */ .submission-items { margin-bottom: var(--space-8); } .submission-items .checklist-rows { margin-bottom: 0; } .submission-items-head { min-width: 0; display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-3); } /* The title and its count wrap as words beside the template button, never letter by letter. */ .submission-items-title { min-width: 0; flex: 1 1 auto; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--space-3); } .submission-items-head h3 { margin: 0; min-width: 0; word-break: keep-all; overflow-wrap: break-word; color: var(--text-primary); font-size: var(--type-subtitle-size); line-height: var(--type-subtitle-line-height); font-weight: var(--type-subtitle-weight); } .submission-items-title > span { color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-variant-numeric: tabular-nums; white-space: nowrap; } .submission-items-head > :last-child { flex: none; align-self: start; } .submission-template-form { margin-bottom: var(--space-4); } .submission-template-menu [data-slot="dropdown-menu-item"] { gap: var(--space-4); } .submission-template-name { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .submission-template-count { color: var(--text-tertiary); font-variant-numeric: tabular-nums; } .submission-rows > * + * { border-top: 1px solid var(--border-subtle); } .checklist-row.submission-row { grid-template-columns: 18px minmax(0, 1fr); } .submission-row span { display: inline; justify-self: auto; text-align: inherit; color: inherit; font: inherit; } .submission-toggle { align-self: start; width: 18px; height: 18px; padding: 0; border: 0; border-radius: 50%; background: transparent; cursor: pointer; } .submission-toggle .checklist-status { top: 0; transition: box-shadow var(--motion-fast); } .submission-toggle:hover .checklist-status { box-shadow: 0 0 0 1px var(--border-strong); } .submission-title { min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: var(--space-1) var(--space-5); padding: 0; border: 0; background: transparent; color: inherit; text-align: start; font: inherit; cursor: pointer; } .submission-title:hover strong { text-decoration: underline; text-decoration-color: var(--border-strong); text-underline-offset: 3px; } .submission-title strong { overflow-wrap: anywhere; } .submission-row .submission-state { color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); white-space: nowrap; } .submission-row.warn .submission-state { color: var(--status-warning); font-weight: var(--weight-medium); } /* A narrow drawer puts the state under the title rather than squeezing either. */ @container checklist-rows (width < 360px) { .submission-title { grid-template-columns: minmax(0, 1fr); } .submission-row .submission-state { white-space: normal; } } .submission-row .submission-meta { min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-4); } .submission-meta > * { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .submission-row .submission-owner { color: var(--text-primary); font-weight: var(--weight-medium); } .submission-chip { display: inline-flex; align-items: center; gap: var(--space-1); padding: 0; border: 0; background: transparent; color: var(--control-active); font: inherit; cursor: pointer; } .submission-chip > span { overflow: hidden; text-overflow: ellipsis; } .submission-chip svg { flex: none; } .submission-chip:hover > span { text-decoration: underline; text-underline-offset: 2px; } .submission-row.warn[data-condition="missing"] .submission-chip { color: var(--text-secondary); text-decoration: line-through; } .submission-form { padding: var(--space-5) var(--space-6) var(--space-6); display: grid; } .submission-add { display: grid; grid-template-columns: 18px minmax(0, 1fr); align-items: center; gap: var(--space-5); padding: var(--space-4) var(--space-6); color: var(--text-tertiary); } .submission-add svg { justify-self: center; } .submission-add input { min-width: 0; height: var(--control-height-compact); padding: 0; border: 0; outline: none; background: transparent; color: var(--text-primary); font-size: var(--type-body-size); line-height: var(--type-body-line-height); } .submission-add input::placeholder { color: var(--text-tertiary); } .submission-add:focus-within { background: var(--control-hover-surface); } .welcome-screen { width: 100%; height: 100%; background: var(--surface-backdrop); position: relative; overflow: hidden; } .welcome-titlebar { position: absolute; z-index: 3; top: 0; left: 0; right: 0; height: 48px; display: flex; justify-content: flex-end; align-items: center; padding: 0 14px; } .welcome-content { position: relative; z-index: 1; width: min(520px, calc(100% - 48px)); height: 100%; margin: auto; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding-bottom: var(--space-10); } .brand-mark { width: 50px; height: 50px; border-radius: 14px; display: grid; place-items: center; color: var(--control-active); } /* The one brand moment: the mark, then a serif title at a size that greets rather than advertises. Chinese takes Songti SC through --display-font, a serif like the Latin; it sets solid, so it opens its tracking a little where the Latin tightens. */ .welcome-content h1 { margin: var(--space-10) 0 0; font-family: var(--display-font); font-size: clamp(36px, 4.4vw, 48px); line-height: 1.08; font-weight: 400; letter-spacing: -.02em; text-wrap: balance; } /* Only the welcome composition enters; busy updates and project contents do not. */ .welcome-content > :not(.busy-label) { animation: welcome-rise var(--motion-slow) both; } .welcome-content > .welcome-actions, .welcome-content > .welcome-more, .welcome-content > .welcome-recents { animation-delay: 60ms; } @keyframes welcome-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } } .welcome-actions { margin-top: var(--space-12); display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-4); } /* The other ways in, last: quieter than the actions and the recent projects above them, and on one line at the width the content column actually has. */ .welcome-more { margin-top: var(--space-8); display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: var(--space-2); } .welcome-more-action { height: var(--control-height-compact); padding: 0 var(--pad-inline-control); border-radius: var(--radius-chrome); background: transparent; color: var(--text-secondary); display: inline-flex; align-items: center; gap: var(--space-3); font-size: var(--type-caption-size); font-weight: var(--weight-regular); white-space: nowrap; } .welcome-more-action:hover { background: var(--border-subtle); color: var(--text-primary); } /* The projects to go back to, and why the last one did not open: the writer's way back, so it comes straight after the actions. Wider than the column above it, so three pages read at a size where a title shows. */ .welcome-recents { width: min(720px, calc(100vw - 64px)); margin-top: var(--space-16); display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); text-align: start; } .welcome-unopened { padding-inline: var(--space-1); } .welcome-recents-title { margin: 0; padding-inline: var(--space-1); color: var(--text-secondary); font-size: var(--type-caption-size); line-height: var(--type-caption-line-height); font-weight: var(--weight-medium); } /* The desk: each project as the first page of its paper, paper-coloured in both themes as the PDF preview draws it, its name in the title serif under it. Cards keep a third of the width however many there are; fewer than three shrink the desk around them, so the title stays at its start. */ .welcome-desk-frame { --desk-count: 3; width: calc((100% + var(--space-8)) * var(--desk-count) / 3 - var(--space-8)); justify-self: center; display: grid; gap: var(--space-4); } .welcome-desk { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(var(--desk-count), minmax(0, 1fr)); gap: var(--space-8); } .welcome-desk-card { width: 100%; padding: 0; border: 0; border-radius: calc(var(--radius-panel) * var(--corner-smoothing)); corner-shape: squircle; background: transparent; color: var(--text-secondary); display: grid; grid-template-columns: minmax(0, 1fr); text-align: start;