Skip to content
Clone
main
2483 lines 51.6 KB CSS
/* Issue workspace: comfortable controls, quiet surfaces and legible state. */
.board-toolbar:has(.board-filters) {
align-items: flex-start;
gap: 8px;
padding-block: 10px;
border-bottom: 1px solid var(--shell-hairline);
background: var(--shell-surface);
}
.board-filters {
display: flex;
min-width: 0;
flex: 1 1 100%;
flex-direction: column;
gap: 8px;
}
.board-filters-row {
position: relative;
display: flex;
min-width: 0;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.board-toolbar-actions {
padding-top: 1px;
gap: 8px;
}
.board-search {
display: flex;
height: 32px;
width: min(360px, 40vw);
min-width: 180px;
flex: 0 0 auto;
align-items: center;
gap: 7px;
padding-inline: 9px;
border: 1px solid var(--shell-hairline);
border-radius: 8px;
background: var(--shell-field);
transition:
border-color 150ms,
box-shadow 150ms;
}
.board-search:focus-within {
border-color: var(--shell-tile);
background: var(--shell-surface);
box-shadow: 0 0 0 3px color-mix(in srgb, var(--shell-focus) 20%, transparent);
}
.board-search input {
font-size: 13px;
}
.board-search-clear {
display: grid;
place-items: center;
width: 22px;
height: 22px;
border-radius: 5px;
}
.board-search-clear:hover {
background: var(--shell-active);
}
.board-segmented {
display: inline-flex;
min-height: 32px;
align-items: center;
padding: 3px;
border-radius: 8px;
background: var(--shell-field);
gap: 2px;
}
.board-segmented > button {
min-height: 26px;
flex-shrink: 0;
padding-inline: 9px;
border-radius: 6px;
color: var(--shell-ink-muted);
font-size: 12px;
white-space: nowrap;
transition:
background 140ms,
color 140ms,
box-shadow 140ms;
}
.board-segmented > button:hover {
color: var(--shell-ink);
}
.board-segmented > button[aria-pressed="true"] {
color: var(--shell-ink-muted);
background: var(--shell-surface);
box-shadow: 0 1px 3px rgb(20 30 60 / 7%);
}
.board-filter-trigger {
display: inline-flex;
height: 32px;
flex-shrink: 0;
align-items: center;
padding-inline: 10px;
gap: 6px;
border: 1px solid var(--shell-hairline);
border-radius: 8px;
background: var(--shell-surface);
font-size: 12.5px;
white-space: nowrap;
}
.board-filter-trigger[aria-expanded="true"] {
border-color: var(--shell-tile);
color: var(--shell-ink-muted);
background: var(--shell-field);
}
.board-filter-trigger:hover {
border-color: var(--shell-tile);
}
.board-filter-popover {
margin-top: 7px;
padding: 6px;
max-width: calc(100vw - 40px);
border-width: 1px;
border-radius: 12px;
box-shadow: 0 12px 36px rgb(20 30 60 / 14%);
}
.board-filter-option {
min-height: 36px;
border-radius: 7px;
gap: 8px;
}
.board-filter-option[aria-selected="true"] {
background: var(--shell-field);
color: var(--shell-ink-muted);
}
.board-filter-option:focus-visible {
outline-offset: -2px;
}
.board-view-tabs {
display: inline-flex;
gap: 2px;
padding: 2px;
border-radius: 8px;
background: var(--shell-field);
}
.board-view-tab {
display: inline-flex;
height: 26px;
flex-shrink: 0;
align-items: center;
gap: 5px;
padding-inline: 10px;
border-radius: 6px;
color: var(--shell-ink-muted);
font-size: 12.5px;
white-space: nowrap;
transition:
background 140ms,
color 140ms,
box-shadow 140ms;
}
.board-view-tab:hover {
color: var(--shell-ink);
}
.board-view-tab[aria-pressed="true"] {
background: var(--shell-surface);
color: var(--shell-ink);
font-weight: 600;
box-shadow: 0 1px 2px rgb(20 30 60 / 12%);
}
.board-filter-count {
display: inline-grid;
min-width: 16px;
height: 16px;
place-items: center;
padding-inline: 4px;
border-radius: 999px;
background: var(--shell-action);
color: #fff;
font-size: 10.5px;
font-weight: 600;
font-variant-numeric: tabular-nums;
}
.board-icon-button {
display: grid;
width: 32px;
height: 32px;
place-items: center;
border: 1px solid var(--shell-hairline);
border-radius: 8px;
background: var(--shell-surface);
color: var(--shell-ink-muted);
transition:
background 140ms,
color 140ms,
border-color 140ms;
}
.board-icon-button:hover,
.board-icon-button[aria-expanded="true"] {
border-color: var(--shell-tile);
background: var(--shell-field);
color: var(--shell-ink);
}
.board-more {
position: relative;
}
.board-more-menu {
position: absolute;
right: 0;
z-index: 30;
margin-top: 6px;
min-width: 168px;
padding: 4px;
border: 1px solid var(--shell-hairline);
border-radius: 10px;
background: var(--shell-surface);
box-shadow: 0 12px 36px rgb(20 30 60 / 14%);
}
.board-more-item {
display: flex;
width: 100%;
min-height: 32px;
align-items: center;
gap: 8px;
padding-inline: 8px;
border-radius: 7px;
color: var(--shell-ink);
font-size: 12.5px;
transition: background 140ms;
}
.board-more-item:hover {
background: var(--shell-field);
}
/*
* 筛选 panel: one popover for the four low-frequency dimensions. Multi-select
* rows apply immediately, and each section carries its own search once the
* option list is long enough to need one.
*/
.board-filter-anchor {
position: relative;
flex-shrink: 0;
}
/* Anchored to the 筛选 trigger and opened leftwards, so it reads as that
button's panel rather than as an extension of the search field. */
.board-filter-panel {
position: absolute;
top: calc(100% + 6px);
right: 0;
z-index: 30;
display: flex;
width: 300px;
max-height: min(560px, calc(100dvh - 220px));
flex-direction: column;
overflow-y: auto;
padding: 8px;
border: 1px solid var(--shell-hairline);
border-radius: 12px;
background: var(--shell-surface);
box-shadow: 0 18px 48px rgb(20 30 60 / 16%);
}
.board-filter-section {
display: flex;
flex-direction: column;
gap: 4px;
padding-block: 5px;
}
.board-filter-section + .board-filter-section {
border-top: 1px solid var(--shell-hairline);
}
.board-filter-section-head {
display: flex;
align-items: center;
gap: 6px;
padding: 2px 8px 3px;
color: var(--shell-ink-muted);
font-size: 11.5px;
font-weight: 600;
letter-spacing: 0.02em;
}
.board-filter-section-count {
display: inline-grid;
min-width: 15px;
height: 15px;
place-items: center;
border-radius: 999px;
background: var(--shell-active);
color: var(--shell-ink);
font-size: 10px;
}
.board-filter-section-search {
display: flex;
height: 28px;
align-items: center;
gap: 6px;
margin: 0 6px 4px;
padding-inline: 8px;
border: 1px solid var(--shell-hairline);
border-radius: 7px;
background: var(--shell-field);
color: var(--shell-ink-muted);
}
.board-filter-section-search input {
min-width: 0;
flex: 1;
background: transparent;
font-size: 12px;
outline: none;
}
.board-filter-options {
display: flex;
max-height: 176px;
flex-direction: column;
gap: 1px;
overflow-y: auto;
}
.board-filter-check {
display: flex;
min-height: 30px;
align-items: center;
gap: 8px;
padding-inline: 8px;
border-radius: 7px;
color: var(--shell-ink);
font-size: 12.5px;
text-align: left;
transition: background 120ms;
}
.board-filter-check:hover {
background: var(--shell-field);
}
.board-filter-check-box {
display: grid;
width: 15px;
height: 15px;
flex-shrink: 0;
place-items: center;
border: 1px solid var(--shell-hairline);
border-radius: 4px;
background: var(--shell-surface);
color: #fff;
transition:
background 120ms,
border-color 120ms;
}
.board-filter-check[aria-checked="true"] .board-filter-check-box {
border-color: var(--shell-action);
background: var(--shell-action);
}
.board-filter-check-dot {
width: 8px;
height: 8px;
flex-shrink: 0;
border-radius: 999px;
}
.board-filter-check-label {
min-width: 0;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.board-filter-check-hint {
flex-shrink: 0;
color: var(--shell-ink-muted);
font-size: 11px;
}
.board-filter-section-empty {
padding: 6px 8px;
color: var(--shell-ink-muted);
font-size: 11.5px;
}
.board-filter-panel-foot {
display: flex;
align-items: center;
gap: 8px;
padding: 7px 4px 2px;
border-top: 1px solid var(--shell-hairline);
}
.board-filter-done {
height: 28px;
margin-left: auto;
padding-inline: 12px;
border-radius: 7px;
background: var(--shell-action);
color: #fff;
font-size: 12px;
font-weight: 600;
}
.board-filter-done:hover {
filter: brightness(1.08);
}
/*
* The summary grows out of the toolbar instead of being inserted into it: a
* `0fr → 1fr` grid row is the one height transition that works without
* measuring, so the list below slides down rather than jumping.
*/
.board-filter-summary {
display: grid;
grid-template-rows: 0fr;
opacity: 0;
transition:
grid-template-rows 200ms ease,
opacity 200ms ease;
}
.board-filter-summary.is-on {
grid-template-rows: 1fr;
opacity: 1;
}
.board-filter-summary-inner {
display: flex;
min-height: 0;
min-width: 0;
flex-wrap: wrap;
align-items: center;
gap: 6px;
overflow: hidden;
}
.board-filter-total {
color: var(--shell-ink-muted);
font-size: 11.5px;
}
.board-filter-chip {
display: inline-flex;
align-items: center;
gap: 5px;
padding: 3px 6px 3px 9px;
border-radius: 999px;
background: var(--shell-field);
color: var(--shell-ink);
font-size: 11.5px;
}
.board-filter-chip > button {
display: grid;
width: 16px;
height: 16px;
place-items: center;
border-radius: 50%;
color: var(--shell-ink-muted);
}
.board-filter-chip > button:hover {
background: var(--shell-active);
color: var(--shell-ink);
}
.board-filter-clear {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 3px 4px;
border-radius: 6px;
color: var(--shell-ink-muted);
font-size: 11.5px;
transition: color 140ms;
}
.board-filter-clear:hover:not(:disabled) {
color: var(--shell-ink);
}
.board-filter-clear:disabled {
opacity: 0.5;
}
/*
* Responsive ladder for the board chrome:
* <1280px the toolbar keeps search + status + 排序 + 筛选, everything else
* already lives in the panel, so only the gaps tighten
* <900px the search takes the full row instead of shrinking forever
* <768px 筛选 becomes a bottom sheet and 新建工单 drops to its icon
*/
@media (max-width: 1280px) {
.board-filters-row {
gap: 6px;
}
.board-search {
width: min(300px, 34vw);
}
}
@media (max-width: 900px) {
.board-search {
width: 100%;
order: -1;
}
}
@media (max-width: 768px) {
.board-toolbar:has(.board-filters) {
padding-block: 8px;
}
.board-filter-panel {
position: fixed;
inset: auto 0 0 0;
width: auto;
max-height: 72dvh;
border-radius: 16px 16px 0 0;
border-bottom: 0;
box-shadow: 0 -18px 48px rgb(20 30 60 / 22%);
}
.board-filter-options {
max-height: none;
}
.board-create-label {
display: none;
}
.board-create-button {
padding-inline: 10px;
}
}
.board-create-button {
display: inline-flex;
height: 32px;
min-height: 32px;
align-items: center;
gap: 6px;
padding-inline: 12px;
border-radius: 8px;
background: var(--shell-action);
color: #fff;
font-size: 13px;
font-weight: 600;
transition:
filter 140ms,
transform 140ms;
}
.board-create-button {
box-shadow: 0 3px 8px rgb(35 39 43 / 5%);
}
.board-create-button:hover {
transform: translateY(-1px);
}
.board-canvas:has(.issue-board-body),
.board-canvas:has(.issue-board-empty) {
padding-top: 20px;
}
.issue-board-body {
gap: 16px;
}
.issue-board-columns {
gap: 16px;
}
.issue-board-column {
--priority-tone: #718096;
width: 284px;
padding: 12px;
gap: 14px;
border: 1px solid color-mix(in srgb, var(--shell-hairline) 76%, transparent);
border-radius: 14px;
background: color-mix(in srgb, var(--priority-tone) 4%, var(--shell-board));
transition:
background 180ms,
border-color 180ms;
}
[data-priority="urgent"] {
--priority-tone: #cb5363;
}
[data-priority="high"] {
--priority-tone: #c67536;
}
[data-priority="medium"] {
--priority-tone: #9b801b;
}
[data-priority="low"] {
--priority-tone: #4c7bc2;
}
[data-priority="none"] {
--priority-tone: #68758a;
}
.issue-board-column[data-drag-over] {
background: var(--shell-active);
border-color: var(--shell-ink-muted);
}
.issue-board-column-header {
height: 30px;
padding: 0 2px;
gap: 8px;
}
.issue-board-column-header > span:first-child {
width: 8px;
height: 8px;
background: var(--priority-tone) !important;
box-shadow: 0 0 0 4px color-mix(in srgb, var(--priority-tone) 9%, transparent);
}
.issue-board-column-header > span:nth-child(2) {
font-size: 13px;
letter-spacing: 0.02em;
}
.issue-board-count {
display: inline-flex;
justify-content: center;
align-items: center;
min-width: 23px;
height: 23px;
padding-inline: 5px;
border: 1px solid var(--shell-hairline);
border-radius: 7px;
background: var(--shell-surface);
font-size: 11px;
font-variant-numeric: tabular-nums;
}
.issue-board-add {
display: grid;
width: 28px;
height: 28px;
place-items: center;
border-radius: 7px;
}
.issue-board-column > div {
padding: 1px 1px 6px;
}
.issue-board-column > div > * + * {
margin-top: 10px;
}
.issue-board-card {
padding: 15px 14px 12px;
border: 1px solid var(--shell-hairline);
border-radius: 11px;
box-shadow: 0 2px 4px rgb(20 30 60 / 3%);
transition:
border-color 150ms,
box-shadow 150ms,
transform 150ms,
opacity 150ms;
}
.issue-board-card:hover {
transform: translateY(-2px);
border-color: var(--shell-tile);
box-shadow: 0 6px 18px rgb(20 30 60 / 7%);
}
.issue-board-card[data-moving] {
opacity: 0.45;
}
.issue-board-card > div:first-child {
flex-wrap: wrap;
row-gap: 8px;
}
.issue-board-card-title {
flex-basis: 100%;
font-size: 13px;
font-weight: 550;
line-height: 1.7;
}
.issue-board-card-title .gitdata-markdown,
.issue-list-title .gitdata-markdown {
color: inherit;
font-size: inherit;
font-weight: inherit;
line-height: inherit;
letter-spacing: inherit;
}
.issue-board-card-meta {
flex-wrap: wrap;
gap: 7px;
margin-top: 14px;
padding-top: 10px;
border-top: 1px solid color-mix(in srgb, var(--shell-hairline) 65%, transparent);
}
.issue-board-card-meta > span[title] {
max-width: 95px;
}
.issue-priority-badge {
padding: 3px 8px;
gap: 5px;
color: color-mix(in srgb, var(--priority-tone) 85%, var(--shell-ink));
background: color-mix(in srgb, var(--priority-tone) 12%, var(--shell-surface));
border-radius: 5px;
font-size: 10px;
line-height: 1.5;
font-weight: 550;
}
.issue-priority-badge::before {
content: "";
width: 5px;
height: 5px;
border-radius: 50%;
background: var(--priority-tone);
}
.issue-state-badge {
padding: 4px 8px;
border-radius: 6px;
color: #278361;
background: color-mix(in srgb, #34a179 12%, var(--shell-surface));
font-weight: 550;
white-space: nowrap;
}
.issue-state-badge[data-state="closed"] {
color: var(--shell-ink-muted);
background: var(--shell-field);
}
.issue-board-column-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
min-height: 134px;
gap: 9px;
border: 1px dashed color-mix(in srgb, var(--priority-tone) 22%, var(--shell-hairline));
border-radius: 10px;
color: var(--shell-ink-muted);
font-size: 12px;
transition:
background 150ms,
color 150ms,
border-color 150ms;
}
.issue-board-column-empty small {
font-size: 10px;
opacity: 0.85;
}
.issue-board-column-empty:hover {
border-color: var(--shell-ink-muted);
color: var(--shell-ink-muted);
background: var(--shell-field);
}
.issue-board-empty {
margin: 0 auto;
align-self: flex-start;
min-height: 360px;
justify-content: center;
padding: 56px 24px;
border: 1px solid var(--shell-hairline);
border-radius: 18px;
background: radial-gradient(ellipse at top, var(--shell-field), var(--shell-surface) 65%);
}
.issue-board-empty-icon {
display: grid;
width: 64px;
height: 64px;
margin-bottom: 14px;
place-items: center;
border: 1px solid var(--shell-tile);
border-radius: 20px;
background: var(--shell-field);
color: var(--shell-ink-muted);
transform: rotate(-5deg);
}
.issue-board-empty > p:first-of-type {
font-size: 18px;
font-weight: 600;
}
.issue-board-empty > p:nth-of-type(2) {
margin-top: 2px;
font-size: 13px;
line-height: 1.8;
}
.issue-board-empty > button {
min-height: 38px;
margin-top: 17px;
border-radius: 9px;
padding-inline: 15px;
}
/*
* List view: Linear-style rows. No header, no cell borders, no card — the row
* itself is the only container, and hover paints it. Priority is a mark you
* can click to change; the trailing facts (milestone / assignees / updated)
* stay muted so the title keeps the ink.
*/
.issue-list {
display: flex;
min-width: 0;
flex-direction: column;
gap: 1px;
padding: 6px 8px;
border-radius: 12px;
background: var(--shell-surface);
}
/* Rows settle in rather than snapping when a filter changes the result set.
No `fill-mode`, so the hover transforms below keep working after the fade. */
.issue-list-row,
.issue-board-card {
animation: issue-row-in 200ms ease;
}
@keyframes issue-row-in {
from {
opacity: 0;
transform: translateY(-3px);
}
to {
opacity: 1;
transform: none;
}
}
.issue-list-row {
display: flex;
min-height: 40px;
min-width: 0;
cursor: pointer;
align-items: center;
gap: 8px;
padding: 0 8px;
border-radius: 8px;
transition: background 120ms ease;
}
/* The list sits on a white surface, so the hover steps down to the canvas
tone instead of vanishing into the page. */
.issue-list-row:hover,
.issue-list-row:focus-within {
background: var(--shell-field);
}
.issue-list-title {
min-width: 0;
flex: 1;
overflow: hidden;
color: var(--shell-ink);
font-size: 13px;
font-weight: 500;
line-height: 1.6;
text-align: left;
text-overflow: ellipsis;
white-space: nowrap;
}
.issue-list-title:hover {
color: color-mix(in srgb, var(--shell-ink) 74%, var(--shell-ink-muted));
}
.issue-list-key {
flex-shrink: 0;
white-space: nowrap;
color: var(--shell-ink);
font-size: 12.5px;
font-weight: 550;
letter-spacing: 0.01em;
}
.issue-list-state {
display: grid;
width: 16px;
flex-shrink: 0;
place-items: center;
color: var(--shell-ink-muted);
}
.issue-list-state[data-state="open"] {
color: #3ba55d;
}
.issue-list-meta {
display: flex;
flex-shrink: 0;
align-items: center;
gap: 10px;
}
.issue-list-chip {
display: inline-flex;
max-width: 190px;
align-items: center;
gap: 6px;
padding: 2px 9px;
border: 1px solid var(--shell-hairline);
border-radius: 999px;
background: var(--shell-surface);
color: var(--shell-ink-muted);
font-size: 11.5px;
line-height: 1.5;
}
.issue-list-dot {
width: 7px;
height: 7px;
flex-shrink: 0;
border-radius: 999px;
}
.issue-list-chip-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.issue-list-date {
min-width: 76px;
flex-shrink: 0;
text-align: right;
color: var(--shell-ink-muted);
font-size: 12px;
font-variant-numeric: tabular-nums;
}
.issue-priority-glyph {
display: grid;
width: 18px;
height: 18px;
place-items: center;
color: var(--shell-ink-muted);
}
.issue-priority-glyph svg {
display: block;
}
.issue-priority-glyph rect {
fill: none;
stroke: currentColor;
stroke-width: 1.1;
opacity: 0.45;
}
.issue-priority-glyph rect.is-on {
fill: currentColor;
stroke: none;
opacity: 0.95;
}
.issue-priority-glyph[data-priority="urgent"] {
color: #e5484d;
}
.issue-priority-glyph[data-priority="high"] {
color: color-mix(in srgb, var(--shell-ink) 82%, var(--shell-ink-muted));
}
/* Square hit area: an icon-only trigger must not be a tall letterbox. */
.board-filter-trigger-icon {
display: grid;
width: 26px;
height: 26px;
place-items: center;
padding: 0;
border-radius: 7px;
background: transparent;
color: var(--shell-ink-muted);
}
.board-filter-trigger-icon:hover,
.board-filter-trigger-icon[aria-expanded="true"] {
background: color-mix(in srgb, var(--shell-ink) 8%, transparent);
color: var(--shell-ink);
}
.issue-board-skeleton {
animation: issue-board-pulse 1.5s ease-in-out infinite alternate;
}
@keyframes issue-board-pulse {
to {
opacity: 0.5;
}
}
/*
* Issue detail, Linear-style: the page is the canvas (no framing cards),
* comments are the only cards, and the right rail is a list of plain rows.
*/
.issue-detail {
display: flex;
max-width: 1180px;
flex-direction: column;
gap: 14px;
margin: 6px auto 64px;
}
.issue-detail-notice {
padding: 6px 10px;
border-radius: 8px;
background: var(--shell-field);
color: var(--shell-ink-muted);
font-size: 12.5px;
}
.issue-detail-topline {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
}
.issue-detail-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
margin-left: auto;
}
.issue-action {
display: inline-flex;
align-items: center;
gap: 6px;
height: 30px;
padding-inline: 9px;
border-radius: 7px;
color: var(--shell-ink-muted);
font-size: 12.5px;
transition:
background 140ms,
color 140ms;
}
.issue-action:hover {
background: var(--shell-field);
color: var(--shell-ink);
}
.issue-action-strong {
color: var(--shell-ink);
font-weight: 600;
}
.issue-action-strong:hover {
background: var(--shell-active);
}
.issue-action-danger {
height: 30px;
padding-inline: 9px;
border-radius: 7px;
color: #b42318;
font-size: 12.5px;
}
.issue-action-danger:hover {
background: color-mix(in srgb, #e5484d 10%, transparent);
color: #b42318;
}
.issue-action-danger[data-armed="true"] {
background: #e5484d;
color: #fff;
font-weight: 600;
}
.issue-detail-layout {
display: flex;
align-items: flex-start;
gap: 48px;
}
.issue-detail-main {
display: flex;
min-width: 0;
max-width: 780px;
flex: 1 1 auto;
flex-direction: column;
gap: 22px;
}
.issue-detail-rail {
display: flex;
width: 268px;
flex-shrink: 0;
flex-direction: column;
gap: 20px;
margin-left: auto;
}
.issue-detail-key {
display: flex;
align-items: center;
gap: 8px;
}
.issue-detail-number {
color: var(--shell-ink-muted);
font-family: var(--font-mono);
font-size: 12px;
}
.issue-detail-title {
margin-top: 10px;
font-size: 24px;
font-weight: 650;
line-height: 1.35;
letter-spacing: -0.02em;
}
.issue-detail-title .gitdata-markdown {
color: inherit;
font-size: inherit;
font-weight: inherit;
line-height: inherit;
letter-spacing: inherit;
}
.issue-detail-title .gitdata-markdown code {
font-size: 0.9em;
}
.issue-detail-desc {
margin-top: 10px;
font-size: 13.5px;
line-height: 1.75;
word-break: break-word;
}
.issue-detail-desc.is-empty {
color: var(--shell-ink-muted);
}
.issue-detail-byline {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
margin-top: 16px;
color: var(--shell-ink-muted);
font-size: 12px;
}
.issue-feed {
display: flex;
flex-direction: column;
gap: 14px;
padding-top: 18px;
border-top: 1px solid var(--shell-hairline);
}
.issue-feed-head {
display: flex;
min-height: 30px;
align-items: center;
gap: 8px;
}
.issue-feed-head h2 {
font-size: 13px;
font-weight: 600;
}
.issue-feed-count {
color: var(--shell-ink-muted);
font-size: 12px;
}
.issue-feed-head-actions {
margin-left: auto;
}
.issue-feed-note {
color: var(--shell-ink-muted);
font-size: 12.5px;
}
.issue-feed-more {
display: inline-flex;
align-self: flex-start;
align-items: center;
gap: 6px;
height: 28px;
padding-inline: 8px;
border-radius: 7px;
color: var(--shell-ink-muted);
font-size: 12px;
transition:
background 140ms,
color 140ms;
}
.issue-feed-more:hover {
background: var(--shell-field);
color: var(--shell-ink);
}
.issue-event {
display: grid;
grid-template-columns: 20px minmax(0, 1fr);
align-items: start;
gap: 10px;
}
.issue-event-icon {
display: grid;
width: 20px;
height: 20px;
place-items: center;
}
.issue-event-dot {
display: grid;
width: 20px;
height: 20px;
place-items: center;
border-radius: 50%;
background: var(--shell-field);
color: var(--shell-ink-muted);
}
.issue-event-stack {
display: flex;
min-width: 0;
flex-direction: column;
gap: 2px;
}
.issue-event-body {
min-width: 0;
padding-top: 1px;
color: var(--shell-ink-muted);
font-size: 12.5px;
line-height: 1.6;
}
.issue-event-actor {
color: var(--shell-ink);
font-weight: 550;
}
.issue-event-extra {
color: var(--shell-ink-muted);
}
/* The changed value is the point of the line: keep it in ink, not in grey. */
.issue-event-value {
padding: 1px 5px;
border-radius: 5px;
background: var(--shell-field);
color: var(--shell-ink);
font-weight: 550;
}
.issue-event-toggle {
display: inline-flex;
align-self: flex-start;
align-items: center;
gap: 4px;
margin-top: 2px;
padding: 2px 6px 2px 4px;
border-radius: 6px;
color: var(--shell-ink-muted);
font-size: 11.5px;
transition:
background 140ms,
color 140ms;
}
.issue-event-toggle:hover {
background: var(--shell-field);
color: var(--shell-ink);
}
.issue-event-time {
color: var(--shell-ink-muted);
font-size: 11.5px;
}
.comment-card {
padding: 14px 16px;
border: 1px solid var(--shell-hairline);
border-radius: 10px;
background: var(--shell-surface);
box-shadow: 0 1px 2px rgb(20 30 60 / 4%);
}
.comment-head {
display: flex;
align-items: center;
gap: 8px;
}
.comment-author {
font-size: 12.5px;
font-weight: 600;
}
.comment-time {
color: var(--shell-ink-muted);
font-size: 11.5px;
}
.comment-actions {
display: flex;
align-items: center;
gap: 2px;
margin-left: auto;
}
.comment-action {
padding: 3px 6px;
border-radius: 6px;
color: var(--shell-ink-muted);
font-size: 11.5px;
transition:
background 140ms,
color 140ms;
}
.comment-action:hover {
background: var(--shell-field);
color: var(--shell-ink);
}
.comment-body {
margin-top: 8px;
font-size: 13px;
line-height: 1.75;
white-space: pre-wrap;
word-break: break-word;
}
.comment-error {
margin-top: 6px;
color: #b42318;
font-size: 12px;
}
.comment-editor {
display: flex;
flex-direction: column;
gap: 8px;
margin-top: 10px;
}
.comment-input {
width: 100%;
min-height: 44px;
padding: 8px 10px;
border: 1px solid var(--shell-hairline);
border-radius: 8px;
background: var(--shell-field);
font-size: 13px;
line-height: 1.7;
outline: none;
resize: vertical;
transition:
border-color 150ms,
background 150ms;
}
.comment-input:focus {
border-color: var(--shell-tile);
background: var(--shell-surface);
}
.comment-replies {
display: flex;
flex-direction: column;
gap: 10px;
margin-top: 12px;
}
.comment-replies .comment-card {
border: 0;
background: var(--shell-board);
box-shadow: none;
}
.comment-reply-row {
display: flex;
align-items: center;
gap: 8px;
margin-top: 12px;
padding-top: 10px;
border-top: 1px solid var(--shell-hairline);
}
.comment-reply-input {
min-width: 0;
flex: 1;
height: 28px;
padding-inline: 2px;
font-size: 12.5px;
outline: none;
}
.comment-send {
display: grid;
width: 26px;
height: 26px;
flex-shrink: 0;
place-items: center;
border-radius: 7px;
color: var(--shell-ink-muted);
transition:
background 140ms,
color 140ms,
opacity 140ms;
}
.comment-send:disabled {
opacity: 0.45;
}
.comment-send:not(:disabled) {
background: var(--shell-action);
color: #fff;
}
.comment-send:not(:disabled):hover {
filter: brightness(1.08);
}
/* One box owns the border: the textarea inside it stays bare. */
.issue-composer {
display: flex;
flex-direction: column;
gap: 8px;
padding: 12px 14px 10px;
transition:
border-color 150ms,
box-shadow 150ms;
}
.issue-composer:focus-within {
border-color: var(--shell-tile);
box-shadow:
0 1px 2px rgb(20 30 60 / 4%),
0 0 0 3px color-mix(in srgb, var(--shell-focus) 16%, transparent);
}
.issue-composer .comment-input {
min-height: 42px;
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
resize: none;
}
.issue-composer .comment-input:focus {
border: 0;
background: transparent;
}
.issue-detail .issue-composer .comment-input:focus-visible {
outline: none;
}
.comment-foot {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 8px;
}
/* Right rail: grouped rows instead of boxes. */
.issue-rail-group {
display: flex;
flex-direction: column;
gap: 4px;
}
.issue-rail-title {
padding-inline: 8px;
color: var(--shell-ink-muted);
font-size: 11.5px;
font-weight: 550;
letter-spacing: 0.02em;
}
.issue-rail-rows {
display: flex;
flex-direction: column;
}
.issue-rail-labels {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
padding: 2px 8px;
}
.issue-rail-empty {
color: var(--shell-ink-muted);
font-size: 12px;
}
.issue-rail-error {
color: #b42318;
font-size: 11.5px;
}
.issue-prop-row {
display: flex;
width: 100%;
height: 30px;
align-items: center;
gap: 8px;
padding-inline: 8px;
border-radius: 7px;
color: var(--shell-ink);
font-size: 12.5px;
transition: background 140ms;
}
.issue-prop-row:hover {
background: var(--shell-field);
}
.issue-prop-icon {
flex-shrink: 0;
color: var(--shell-ink-muted);
}
.issue-prop-label {
flex-shrink: 0;
color: var(--shell-ink-muted);
}
.issue-prop-value {
display: flex;
min-width: 0;
align-items: center;
gap: 6px;
margin-left: auto;
}
.issue-prop-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.issue-prop-text.is-empty {
color: var(--shell-ink-muted);
}
.issue-prop-chevron {
flex-shrink: 0;
color: var(--shell-ink-muted);
opacity: 0;
transition: opacity 140ms;
}
.issue-prop-row:hover .issue-prop-chevron,
.issue-prop-row[aria-expanded="true"] .issue-prop-chevron {
opacity: 0.7;
}
.issue-prop-clear {
display: grid;
width: 18px;
height: 18px;
flex-shrink: 0;
place-items: center;
border-radius: 5px;
color: var(--shell-ink-muted);
}
.issue-prop-clear:hover {
background: var(--shell-active);
color: var(--shell-ink);
}
/* The date field is a rail row like the others; the native input only holds
the value and feeds the picker. */
.issue-prop-row-action {
position: relative;
padding-inline: 8px;
}
.issue-prop-target {
display: flex;
min-width: 0;
flex: 1;
align-items: center;
gap: 8px;
text-align: left;
}
.issue-prop-date-sr {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
border: 0;
clip-path: inset(50%);
opacity: 0;
pointer-events: none;
}
.issue-prop-popover {
position: absolute;
top: calc(100% + 4px);
right: 0;
z-index: 40;
width: 248px;
max-height: 280px;
overflow-y: auto;
}
.issue-prop-add {
display: inline-flex;
align-items: center;
gap: 4px;
height: 24px;
padding-inline: 6px;
border-radius: 6px;
color: var(--shell-ink-muted);
font-size: 12px;
transition:
background 140ms,
color 140ms;
}
.issue-prop-add:hover {
background: var(--shell-field);
color: var(--shell-ink);
}
.issue-check {
display: grid;
width: 14px;
height: 14px;
flex-shrink: 0;
place-items: center;
border: 1px solid var(--shell-tile);
border-radius: 4px;
color: #fff;
transition:
background 120ms,
border-color 120ms;
}
.issue-check.is-on {
border-color: var(--shell-ink);
background: var(--shell-ink);
}
.issue-pull-links {
display: flex;
flex-direction: column;
}
.issue-pull-card {
position: relative;
display: flex;
flex-direction: column;
gap: 3px;
margin-bottom: 6px;
padding: 8px 26px 8px 10px;
border-radius: 9px;
background: var(--shell-field);
}
.issue-pull-card-head {
display: flex;
min-width: 0;
align-items: center;
gap: 6px;
color: var(--shell-ink);
font-size: 12.5px;
}
.issue-pull-card-head > svg {
flex: none;
}
.issue-pull-card-title {
min-width: 0;
flex: 1 1 auto;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/*
* 状态徽标不许被长标题挤扁:flex:none + nowrap 保持一行,底色跟随 data-state
* 的颜色(currentColor),与看板状态徽标观感一致。
*/
.issue-pull-state {
flex: none;
padding: 0 6px;
border-radius: 999px;
background: color-mix(in srgb, currentColor 12%, transparent);
font-size: 11px;
font-weight: 600;
line-height: 18px;
white-space: nowrap;
}
.issue-pull-card-foot {
display: flex;
min-width: 0;
align-items: center;
gap: 6px;
}
.issue-pull-branch {
min-width: 0;
flex: 1 1 auto;
overflow: hidden;
color: var(--shell-ink-muted);
font-family: var(--font-mono);
font-size: 11px;
text-overflow: ellipsis;
white-space: nowrap;
}
.issue-pull-branch-base {
flex: 0 1 auto;
}
.issue-pull-arrow {
flex: none;
color: var(--shell-ink-muted);
font-size: 11px;
}
.issue-pull-card-remove {
position: absolute;
top: 8px;
right: 8px;
}
.issue-pull-state[data-state="open"] {
color: #3ba55d;
}
.issue-pull-state[data-state="merged"] {
color: #8e4ec6;
}
.issue-pull-state[data-state="closed"] {
color: #b42318;
}
.issue-pull-picker {
display: flex;
flex-direction: column;
gap: 2px;
margin-top: 4px;
padding: 4px;
border: 1px solid var(--shell-hairline);
border-radius: 9px;
}
.issue-pull-picker-foot {
display: flex;
align-items: center;
gap: 6px;
padding: 2px 4px 4px;
}
.issue-pull-cancel {
padding: 4px 8px;
border-radius: 6px;
color: var(--shell-ink-muted);
font-size: 11.5px;
transition:
background 140ms,
color 140ms;
}
.issue-pull-cancel:hover {
background: var(--shell-field);
color: var(--shell-ink);
}
.issue-more {
position: relative;
}
.issue-more-menu {
position: absolute;
top: calc(100% + 6px);
right: 0;
z-index: 30;
min-width: 168px;
padding: 4px;
border: 1px solid var(--shell-hairline);
border-radius: 10px;
background: var(--shell-surface);
box-shadow: 0 14px 36px rgb(20 30 60 / 16%);
}
.issue-more-danger {
display: flex;
width: 100%;
min-height: 30px;
align-items: center;
gap: 8px;
padding-inline: 8px;
border-radius: 7px;
font-size: 12.5px;
}
.issue-pull-state {
color: var(--shell-ink-muted);
}
.issue-link-button {
align-self: flex-start;
height: 28px;
margin: 4px 0 0 8px;
padding-inline: 10px;
border-radius: 7px;
background: var(--shell-active);
font-size: 12px;
font-weight: 550;
transition: background 140ms;
}
.issue-link-button:not(:disabled):hover {
background: var(--shell-tile);
}
.issue-link-button:disabled {
opacity: 0.5;
}
/*
* Create/edit issue dialog, Linear's composer: breadcrumb header, bare
* title/description fields, and one row of chips above the primary action.
*/
.issue-form-dialog {
padding: 18px 22px 16px;
border-radius: 18px;
}
.issue-form-dialog .issue-dialog-header {
margin-bottom: 4px;
align-items: center;
}
.issue-form-dialog .issue-dialog-content {
overflow: visible;
padding-right: 0;
}
.issue-form-dialog .issue-dialog-footer {
margin-top: 16px;
padding-top: 0;
border-top: 0;
}
.issue-form-head {
display: flex;
min-width: 0;
align-items: center;
gap: 6px;
}
.issue-form-head > svg {
flex-shrink: 0;
color: var(--shell-ink-muted);
}
.issue-form-team {
display: inline-flex;
height: 22px;
align-items: center;
padding-inline: 8px;
border-radius: 6px;
background: var(--shell-field);
color: var(--shell-ink);
font-size: 11.5px;
font-weight: 600;
}
.issue-form-kicker {
overflow: hidden;
color: var(--shell-ink-muted);
font-size: 12.5px;
text-overflow: ellipsis;
white-space: nowrap;
}
.issue-form-body {
display: flex;
flex-direction: column;
gap: 2px;
}
.issue-form-title-row {
display: flex;
align-items: center;
gap: 10px;
}
.issue-form-dialog .issue-form-title {
width: 100%;
height: 44px;
padding: 0;
border: 0;
background: transparent;
color: var(--shell-ink);
font-size: 19px;
font-weight: 600;
letter-spacing: -0.015em;
outline: none;
}
.issue-form-dialog .issue-form-summary {
width: 100%;
height: 32px;
padding: 0;
border: 0;
background: transparent;
color: var(--shell-ink);
font-size: 13.5px;
outline: none;
}
.issue-form-dialog .issue-form-desc {
width: 100%;
min-height: 76px;
max-height: 300px;
margin-top: 6px;
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
color: var(--shell-ink);
font-size: 13px;
line-height: 1.75;
outline: none;
resize: none;
overflow-y: auto;
}
.issue-form-dialog .issue-form-desc:focus {
border: 0;
background: transparent;
box-shadow: none;
}
.issue-form-dialog :is(.issue-form-title, .issue-form-summary, .issue-form-desc):focus-visible {
outline: none;
}
.issue-form-dialog :is(.issue-form-title, .issue-form-summary, .issue-form-desc)::placeholder {
color: var(--shell-ink-muted);
}
.issue-form-count {
flex-shrink: 0;
color: var(--shell-ink-muted);
font-size: 11px;
font-variant-numeric: tabular-nums;
}
.issue-form-preview {
width: 100%;
min-height: 76px;
margin-top: 6px;
padding: 0;
}
.issue-form-desc-tools {
display: flex;
justify-content: flex-end;
}
.issue-form-preview-toggle {
height: 24px;
padding-inline: 6px;
border-radius: 6px;
color: var(--shell-ink-muted);
font-size: 12px;
transition:
background 140ms,
color 140ms;
}
.issue-form-preview-toggle:hover {
background: var(--shell-field);
color: var(--shell-ink);
}
.issue-form-bar {
display: flex;
width: 100%;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.issue-form-chips {
display: flex;
min-width: 0;
flex: 1 1 auto;
flex-wrap: wrap;
align-items: center;
gap: 6px;
}
.issue-form-submit {
display: flex;
margin-left: auto;
align-items: center;
gap: 8px;
}
.issue-form-chip {
position: relative;
display: inline-flex;
height: 28px;
align-items: center;
gap: 6px;
padding-inline: 10px;
border: 1px solid var(--shell-hairline);
border-radius: 999px;
background: transparent;
color: var(--shell-ink-muted);
font-size: 12px;
transition:
background 140ms,
color 140ms;
}
.issue-form-chip > svg {
flex-shrink: 0;
}
.issue-form-chip.is-button:hover,
.issue-form-chip.is-button:focus-within {
background: var(--shell-field);
color: var(--shell-ink);
}
.issue-form-chip.is-disabled {
opacity: 0.55;
}
.issue-form-chip-main {
display: inline-flex;
height: 100%;
align-items: center;
gap: 6px;
padding: 0;
color: inherit;
font-size: inherit;
}
.issue-chip-text {
max-width: 150px;
overflow: hidden;
color: var(--shell-ink);
text-overflow: ellipsis;
white-space: nowrap;
}
.issue-chip-text.is-empty {
color: var(--shell-ink-muted);
}
.issue-form-attach {
display: grid;
width: 28px;
height: 28px;
flex-shrink: 0;
place-items: center;
border: 1px solid var(--shell-hairline);
border-radius: 999px;
color: var(--shell-ink-muted);
transition:
background 140ms,
color 140ms;
}
.issue-form-attach:hover {
background: var(--shell-field);
color: var(--shell-ink);
}
.issue-form-chip.is-draft {
max-width: 220px;
}
.issue-form-chip.is-draft.is-failed {
border-color: color-mix(in srgb, #e5484d 45%, var(--shell-hairline));
color: #b42318;
}
.issue-chip-size {
flex-shrink: 0;
color: var(--shell-ink-muted);
font-size: 11px;
font-variant-numeric: tabular-nums;
}
.issue-chip-dot {
width: 8px;
height: 8px;
flex-shrink: 0;
border-radius: 50%;
}
.issue-chip-clear {
display: grid;
width: 16px;
height: 16px;
flex-shrink: 0;
place-items: center;
border-radius: 50%;
color: var(--shell-ink-muted);
}
.issue-chip-clear:hover {
background: var(--shell-active);
color: var(--shell-ink);
}
.issue-chip-date {
position: absolute;
right: 10px;
bottom: 0;
width: 1px;
height: 1px;
opacity: 0;
pointer-events: none;
}
/* Attachments under the issue description. */
.issue-attachments {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
margin-top: 14px;
}
.issue-attachment {
position: relative;
display: inline-flex;
max-width: 100%;
align-items: center;
}
.issue-attachment.is-file {
height: 30px;
padding-inline: 10px;
border: 1px solid var(--shell-hairline);
border-radius: 8px;
background: var(--shell-surface);
transition:
border-color 140ms,
background 140ms;
}
.issue-attachment.is-file:hover {
border-color: var(--shell-tile);
background: var(--shell-field);
}
.issue-attachment-link {
display: inline-flex;
min-width: 0;
align-items: center;
gap: 7px;
padding: 0;
border: 0;
background: transparent;
color: var(--shell-ink);
font-size: 12.5px;
}
.issue-attachment-link > svg {
flex-shrink: 0;
color: var(--shell-ink-muted);
}
.issue-attachment-name {
max-width: 240px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.issue-attachment-size {
flex-shrink: 0;
color: var(--shell-ink-muted);
font-size: 11.5px;
font-variant-numeric: tabular-nums;
}
.issue-attachment-image {
display: block;
overflow: hidden;
padding: 0;
border: 1px solid var(--shell-hairline);
border-radius: 8px;
background: var(--shell-field);
line-height: 0;
transition: border-color 140ms;
}
.issue-attachment-image:hover {
border-color: var(--shell-tile);
}
.issue-attachment-image img {
display: block;
width: 132px;
height: 88px;
object-fit: cover;
}
.issue-attachment-remove {
position: absolute;
top: -6px;
right: -6px;
display: grid;
width: 18px;
height: 18px;
place-items: center;
border: 1px solid var(--shell-hairline);
border-radius: 50%;
background: var(--shell-surface);
color: var(--shell-ink-muted);
opacity: 0;
transition:
opacity 140ms,
color 140ms;
}
.issue-attachment:hover .issue-attachment-remove,
.issue-attachment:focus-within .issue-attachment-remove {
opacity: 1;
}
.issue-attachment-remove:hover {
color: #b42318;
}
/* The dialog's FilterMenus wear the same chip and open upwards. */
.issue-form-bar .board-filter-trigger {
height: 28px;
padding-inline: 10px;
gap: 6px;
border: 1px solid var(--shell-hairline);
border-radius: 999px;
background: transparent;
color: var(--shell-ink-muted);
font-size: 12px;
}
.issue-form-bar .board-filter-trigger:hover,
.issue-form-bar .board-filter-trigger[aria-expanded="true"] {
border-color: var(--shell-hairline);
background: var(--shell-field);
color: var(--shell-ink);
}
.issue-form-bar .board-filter-trigger-value {
max-width: 150px;
}
.issue-form-bar .board-filter-chevron {
opacity: 0;
transition: opacity 140ms;
}
.issue-form-bar .board-filter-trigger:hover .board-filter-chevron,
.issue-form-bar .board-filter-trigger[aria-expanded="true"] .board-filter-chevron {
opacity: 0.7;
}
.issue-form-bar .board-filter-popover {
top: auto;
bottom: calc(100% + 6px);
margin: 0;
}
.issue-form-popover {
position: absolute;
bottom: calc(100% + 6px);
left: 0;
z-index: 40;
width: 248px;
max-height: 280px;
overflow-y: auto;
}
.issue-form-popover.is-right {
left: auto;
right: 0;
}
/* Bare filter trigger = a rail row that opens the picker. */
.board-filter-trigger-bare {
width: 100%;
height: 30px;
justify-content: flex-start;
gap: 8px;
padding-inline: 8px;
border: 0;
border-radius: 7px;
background: transparent;
color: var(--shell-ink);
}
.board-filter-trigger-bare:hover,
.board-filter-trigger-bare[aria-expanded="true"] {
background: var(--shell-field);
}
.board-filter-trigger-bare .board-filter-leading,
.board-filter-trigger-bare .board-filter-leading > span {
color: var(--shell-ink-muted);
}
.board-filter-trigger-bare .board-filter-trigger-value {
max-width: 150px;
margin-left: auto;
}
.board-filter-trigger-bare .board-filter-chevron {
opacity: 0;
transition: opacity 140ms;
}
.board-filter-trigger-bare:hover .board-filter-chevron,
.board-filter-trigger-bare[aria-expanded="true"] .board-filter-chevron {
opacity: 0.7;
}
.issue-dialog-overlay {
z-index: 60;
background: rgb(22 28 46 / 42%);
backdrop-filter: blur(5px);
}
.issue-dialog {
max-height: min(90dvh, 880px);
padding: 26px;
border-width: 1px;
border-radius: 20px;
box-shadow: 0 24px 80px rgb(10 20 40 / 22%);
outline: none;
}
.issue-dialog-header {
margin-bottom: 22px;
}
.issue-dialog-header h2 {
font-size: 21px;
font-weight: 650;
line-height: 1.4;
letter-spacing: -0.02em;
}
.issue-dialog-header p {
margin-top: 7px;
line-height: 1.75;
font-size: 12px;
}
.issue-dialog-close {
display: grid;
place-items: center;
width: 30px;
height: 30px;
margin-top: -3px;
margin-right: -6px;
border-radius: 8px;
}
.issue-dialog-close:hover {
background: var(--shell-field);
}
.issue-dialog-content {
padding-right: 3px;
}
.issue-dialog-content > * + * {
margin-top: 20px;
}
.issue-dialog-footer {
gap: 9px;
padding-top: 18px;
margin-top: 22px;
border-top: 1px solid var(--shell-hairline);
}
.issue-field-label {
display: inline-block;
font-size: 12px;
line-height: 1.6;
font-weight: 550;
letter-spacing: 0;
}
.issue-field-input,
.issue-dialog textarea {
border-width: 1px;
border-radius: 9px;
background: var(--shell-field);
font-size: 13px;
transition:
border-color 150ms,
box-shadow 150ms;
}
.issue-field-input {
height: 42px;
padding-inline: 12px;
}
.issue-field-small {
height: 34px;
}
.issue-field-input:focus,
.issue-dialog textarea:focus {
border-color: var(--shell-ink-muted);
box-shadow: 0 0 0 3px rgb(35 39 43 / 5%);
}
.issue-field-input[aria-invalid="true"] {
border-color: #cb5363;
}
.issue-picker-option {
border: 1px solid var(--shell-hairline);
padding: 6px 10px;
}
.issue-picker-option[aria-pressed="false"] {
background: var(--shell-field) !important;
color: var(--shell-ink-muted) !important;
}
.issue-picker-option[aria-pressed="true"] {
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--shell-ink) 15%, transparent);
}
.issue-dialog [role="tablist"] {
gap: 6px;
border-bottom-width: 1px;
padding-bottom: 2px;
}
.issue-dialog [role="tab"] {
padding: 9px 14px;
}
.issue-dialog [role="tab"][aria-selected="true"] {
background: var(--shell-field);
border-radius: 7px 7px 0 0;
}
:is(.board-filters, .issue-board-body, .issue-board-empty, .issue-dialog, .issue-detail)
:is(button, a, input, select, textarea):focus-visible {
outline: 2px solid var(--shell-ink-muted);
outline-offset: 3px;
}
:is(.board-filters, .issue-dialog, .issue-detail) :is(input, textarea):focus-visible {
outline: none;
}
.issue-detail :is(button, a, input, textarea):focus-visible {
outline-offset: 1px;
}
.issue-detail .comment-input:focus-visible,
.issue-detail .comment-reply-input:focus-visible {
outline: 2px solid var(--shell-ink-muted);
outline-offset: 1px;
}
@media (max-width: 1024px) {
.board-filters {
flex-basis: 100%;
}
.board-toolbar-actions {
margin-left: 0;
}
.issue-detail-layout {
gap: 32px;
}
.issue-detail-rail {
width: 240px;
}
}
@media (max-width: 700px) {
.board-toolbar:has(.board-filters) {
gap: 12px;
padding-block: 14px;
}
.board-search {
max-width: none;
flex-basis: 100%;
}
.board-filters {
gap: 7px;
}
.board-filter-trigger:not(.board-filter-trigger-bare) {
height: 34px;
}
.board-filter-trigger:not(.board-filter-trigger-bare) > span {
max-width: 100px;
}
.board-filter-popover {
width: 205px;
}
.issue-board-column {
width: min(284px, 78vw);
}
.issue-board-columns {
gap: 12px;
}
.issue-board-empty {
min-height: 320px;
padding-inline: 18px;
}
.issue-board-empty > p:first-of-type {
font-size: 17px;
}
.issue-detail-layout {
flex-direction: column;
gap: 26px;
}
.issue-detail-main {
width: 100%;
max-width: none;
}
.issue-detail-rail {
width: 100%;
}
.issue-detail-actions {
flex-basis: 100%;
margin-left: 0;
}
.issue-detail-title {
font-size: 21px;
}
.issue-dialog {
max-height: 92dvh;
padding: 20px;
border-radius: 16px;
}
.issue-dialog-overlay {
padding: 12px;
}
.issue-form-metadata {
grid-template-columns: 1fr;
}
.issue-dialog-content .flex:has(> input[type="date"]) {
flex-wrap: wrap;
}
.issue-dialog-content .flex:has(> input[name="new-label-name"]) {
flex-wrap: wrap;
}
.issue-dialog-content input[name="milestone-name"] {
min-width: 150px;
}
}
@media (prefers-reduced-motion: reduce) {
.issue-board-skeleton {
animation: none;
}
.issue-list-row,
.issue-board-card {
animation: none;
}
.board-filter-summary {
transition: none;
}
.issue-board-card:hover,
.board-create-button:hover {
transform: none;
}
}
/* ------------------------------------------------- 问题集管理(Linear 风格) --- */
.issue-dialog.issue-manage-dialog {
padding: 0;
border: 0;
border-radius: 14px;
overflow: hidden;
box-shadow:
0 24px 60px rgb(15 20 35 / 24%),
0 2px 8px rgb(15 20 35 / 12%);
}
.issue-manage-dialog .issue-dialog-header {
margin: 0;
align-items: center;
padding: 13px 18px;
border-bottom: 1px solid var(--shell-hairline);
}
.issue-manage-dialog .issue-dialog-content {
padding: 14px 18px 16px;
overflow: visible;
}
.issue-manage-dialog .issue-dialog-footer {
margin: 0;
padding: 11px 18px;
border-top: 1px solid var(--shell-hairline);
background: var(--shell-board);
}
.issue-manage-tabs {
display: inline-flex;
gap: 2px;
padding: 2px;
border-radius: 8px;
background: var(--shell-field);
}
.issue-manage-dialog .issue-manage-tab {
height: 26px;
padding: 0 12px;
border: 0;
border-radius: 6px;
background: transparent;
color: var(--shell-ink-muted);
font-size: 12.5px;
font-weight: 500;
transition:
background 140ms,
color 140ms,
box-shadow 140ms;
}
.issue-manage-dialog .issue-manage-tab:hover {
color: var(--shell-ink);
}
.issue-manage-dialog .issue-manage-tab[data-active] {
background: var(--shell-surface);
color: var(--shell-ink);
box-shadow: 0 1px 2px rgb(20 30 60 / 14%);
}
.issue-manage-body {
display: flex;
flex-direction: column;
gap: 14px;
}
.issue-manage-field {
display: flex;
flex-direction: column;
gap: 6px;
}
.issue-manage-label {
color: var(--shell-ink);
font-size: 12px;
font-weight: 550;
}
.issue-manage-input {
width: 100%;
height: 34px;
padding: 0 10px;
border: 1px solid var(--shell-hairline);
border-radius: 8px;
background: var(--shell-surface);
color: var(--shell-ink);
font-size: 13px;
outline: none;
transition:
border-color 140ms,
box-shadow 140ms;
}
.issue-manage-input:disabled {
opacity: 0.6;
}
/*
* Linear-quiet fields: one hairline, a slightly deeper hairline on hover, and
* a soft grey ring on focus. The shared workspace rules (and the older
* `.issue-field-input:focus`) draw a near-black frame there, which reads as an
* error state instead of "selected" — so every field inside this dialog is
* restated here, at a specificity that wins over those.
*/
.issue-manage-dialog :is(input, textarea, select):not([type="checkbox"]):not([type="radio"]) {
border: 1px solid var(--shell-hairline);
border-radius: 8px;
background: var(--shell-surface);
box-shadow: none;
transition:
border-color 140ms ease,
box-shadow 140ms ease,
background 140ms ease;
}
.issue-manage-dialog
:is(input, textarea, select):not([type="checkbox"]):not([type="radio"]):hover:not(:focus):not(:disabled) {
border-color: color-mix(in srgb, var(--shell-ink) 18%, transparent);
}
.issue-manage-dialog :is(input, textarea, select):not([type="checkbox"]):not([type="radio"]):focus {
border-color: color-mix(in srgb, var(--shell-focus) 55%, transparent);
outline: none;
box-shadow: 0 0 0 3px color-mix(in srgb, var(--shell-focus) 16%, transparent);
}
.issue-manage-dialog .issue-manage-textarea {
height: auto;
min-height: 74px;
padding: 8px 10px;
line-height: 1.65;
resize: vertical;
}
.issue-manage-prefix {
width: 168px;
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 12.5px;
letter-spacing: 0.06em;
}
.issue-manage-prefix.is-invalid {
border-color: #e5484d;
}
.issue-manage-hint {
color: var(--shell-ink-muted);
font-size: 11.5px;
line-height: 1.55;
}
.issue-manage-error {
color: #b42318;
font-size: 11.5px;
line-height: 1.55;
}
.issue-manage-stats {
color: var(--shell-ink-muted);
font-size: 11.5px;
}
.issue-manage-footer {
display: flex;
width: 100%;
align-items: center;
gap: 8px;
}
.issue-manage-footer-actions {
display: flex;
margin-left: auto;
align-items: center;
gap: 8px;
}