408 lines
9.4 KiB
CSS
408 lines
9.4 KiB
CSS
/* The takeover seats where the input card sits, centered on the InputBar
|
||
axis at the shared content width (input card - 32): sides = clearance +
|
||
16px so the relation also holds on narrow viewports. */
|
||
.frame {
|
||
display: flex;
|
||
justify-content: center;
|
||
padding: 6px calc(var(--dsh-composer-side-clearance) + 16px) 10px;
|
||
}
|
||
|
||
/* Figma Input 973:36348 body over the 1019:36938 header: no banner strip —
|
||
the card keeps zero padding and sections carry their own insets. */
|
||
.card {
|
||
display: flex;
|
||
flex-direction: column;
|
||
width: 100%;
|
||
max-width: var(--dsh-chat-content-width);
|
||
/* Composer seat sits in a fixed-height conversation column (overflow
|
||
hidden): cap the card against the viewport and scroll the option list
|
||
so header and footer actions stay reachable on long batches. */
|
||
max-height: min(60vh, 520px);
|
||
padding: 0 0 10px;
|
||
border: 1px solid var(--dsw-alias-border-l2-darkmode-thin);
|
||
border-radius: 20px;
|
||
background: var(--dsw-specific-input-major);
|
||
box-shadow: var(--dsw-shadow-lv2);
|
||
color: var(--dsw-alias-label-primary);
|
||
overflow: hidden;
|
||
/* Elevated surface in dark, same as the menus: the body inside scrolls
|
||
once the card hits the cap above, so the thumb takes the l2 pair. Declared
|
||
on the card because the elevation belongs to the surface, and the custom
|
||
properties inherit down to `.body` (see ui-theme styles/scrollbar.css
|
||
for the rebinding contract). */
|
||
--dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);
|
||
--dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);
|
||
}
|
||
|
||
.card,
|
||
.card * {
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
/* Figma 1019:36938 header, user-tuned: heading block left, close right; the
|
||
pager sits in the footer to balance the card. */
|
||
.header {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
justify-content: space-between;
|
||
gap: 16px;
|
||
flex-shrink: 0;
|
||
padding: 20px 16px 0 24px;
|
||
}
|
||
|
||
.headingBlock {
|
||
min-width: 0;
|
||
}
|
||
|
||
.eyebrow {
|
||
/* Eyebrow-to-title gap widened from the figma 2px (user-tuned). */
|
||
margin-bottom: 5px;
|
||
color: var(--dsw-alias-label-tertiary);
|
||
font-size: 11px;
|
||
line-height: 16px;
|
||
}
|
||
|
||
.title {
|
||
margin: 0;
|
||
font-size: 16px;
|
||
line-height: 22px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.detail {
|
||
margin: 0 2px 8px;
|
||
}
|
||
|
||
.footerActions {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.pager {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.progress {
|
||
padding: 0 4px;
|
||
color: var(--dsw-alias-label-secondary);
|
||
font-size: 14px;
|
||
line-height: 24px;
|
||
font-weight: 500;
|
||
white-space: nowrap;
|
||
/* Narrow the plain spaces around the slash without touching glyph tracking. */
|
||
word-spacing: -2px;
|
||
}
|
||
|
||
.iconButton {
|
||
display: grid;
|
||
place-items: center;
|
||
width: 24px;
|
||
height: 24px;
|
||
padding: 0;
|
||
border: none;
|
||
border-radius: 999px;
|
||
background: transparent;
|
||
color: var(--dsw-alias-label-tertiary);
|
||
cursor: pointer;
|
||
}
|
||
|
||
.iconButton:hover:not(:disabled) {
|
||
background: var(--dsw-alias-interactive-bg-hover);
|
||
color: var(--dsw-alias-label-primary);
|
||
}
|
||
|
||
.iconButton:disabled {
|
||
color: var(--dsw-alias-label-dimmed);
|
||
cursor: default;
|
||
}
|
||
|
||
.body {
|
||
display: flex;
|
||
flex: 1 1 auto;
|
||
flex-direction: column;
|
||
min-height: 0;
|
||
overflow-y: auto;
|
||
overscroll-behavior: contain;
|
||
}
|
||
|
||
.options {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 1px;
|
||
margin: 8px 0 0;
|
||
padding: 4px 12px;
|
||
}
|
||
|
||
.option {
|
||
display: flex;
|
||
/* flex-start, not center: with a wrapped description the indicator must
|
||
stay on the FIRST line (centering drifts it down the taller copy block).
|
||
The 8px padding makes a single-line row 40px exactly, so nothing reads
|
||
as top-heavy; .number/.checkbox re-center against the first line box. */
|
||
align-items: flex-start;
|
||
gap: 8px;
|
||
width: 100%;
|
||
min-height: 40px;
|
||
/* Rows are the scroll content, never the slack absorber: a shrinkable row
|
||
collapses to min-height while its wrapped copy keeps the taller
|
||
intrinsic height, and centered content then paints outside the row box —
|
||
over the title and the next row. Overflow belongs to .options. */
|
||
flex-shrink: 0;
|
||
padding: 8px 12px 8px 8px;
|
||
border: 1px solid transparent;
|
||
border-radius: 12px;
|
||
background: transparent;
|
||
color: inherit;
|
||
text-align: left;
|
||
cursor: pointer;
|
||
transition: background-color 120ms ease, border-color 120ms ease;
|
||
}
|
||
|
||
.option:hover:not(:disabled),
|
||
.optionSelected {
|
||
background: var(--dsw-alias-interactive-bg-hover);
|
||
}
|
||
|
||
.optionSelected {
|
||
border-color: var(--dsw-alias-border-l2);
|
||
}
|
||
|
||
.option:disabled {
|
||
cursor: default;
|
||
}
|
||
|
||
/* Leading indicator (figma 20×20, radius 6): single-select shows the option
|
||
number, multi-select swaps in a checkbox; the custom-answer row follows —
|
||
its checkbox mirrors the typed draft (styling only, exclusivity holds). */
|
||
.number {
|
||
display: grid;
|
||
place-items: center;
|
||
flex: 0 0 20px;
|
||
width: 20px;
|
||
height: 20px;
|
||
/* (24px first-line box − 20px indicator) / 2: centers the indicator against
|
||
the first text line under the row's flex-start alignment. */
|
||
margin-top: 2px;
|
||
border-radius: 6px;
|
||
background: var(--dsw-alias-bg-overlay);
|
||
color: var(--dsw-alias-label-secondary);
|
||
font-size: 12px;
|
||
font-weight: 500;
|
||
line-height: 18px;
|
||
}
|
||
|
||
/* Multi-select box (figma 1055:41594, user-tuned down to 14×14): a radius-4
|
||
box centered in the 20px indicator seat; the box itself is the ::before
|
||
layer so the check icon stacks over it in the same grid cell. */
|
||
.checkbox {
|
||
display: grid;
|
||
place-items: center;
|
||
flex: 0 0 20px;
|
||
width: 20px;
|
||
height: 20px;
|
||
/* Same first-line centering as .number under flex-start alignment. */
|
||
margin-top: 2px;
|
||
}
|
||
|
||
.checkbox::before {
|
||
content: '';
|
||
grid-area: 1 / 1;
|
||
width: 14px;
|
||
height: 14px;
|
||
border: 1px solid var(--dsw-alias-border-l4);
|
||
border-radius: 4px;
|
||
transition: background-color 120ms ease, border-color 120ms ease;
|
||
}
|
||
|
||
.checkbox > svg {
|
||
grid-area: 1 / 1;
|
||
}
|
||
|
||
/* Checked: label-primary fill with a primary-foreground check — the pair
|
||
inverts with the theme (dark fill in light mode, light fill in dark mode). */
|
||
.checkboxChecked {
|
||
color: var(--dsw-alias-label-primary-foreground);
|
||
}
|
||
|
||
.checkboxChecked::before {
|
||
border-color: var(--dsw-alias-label-primary);
|
||
background: var(--dsw-alias-label-primary);
|
||
}
|
||
|
||
.optionCopy {
|
||
min-width: 0;
|
||
flex: 1;
|
||
}
|
||
|
||
.optionLine {
|
||
display: flex;
|
||
align-items: baseline;
|
||
flex-wrap: wrap;
|
||
gap: 2px 6px;
|
||
}
|
||
|
||
.optionLabel {
|
||
font-size: 14px;
|
||
line-height: 24px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.badge {
|
||
padding: 0 4px;
|
||
border-radius: 6px;
|
||
background: var(--dsw-specific-sidebar-nav-item-active-accent);
|
||
color: var(--dsw-alias-button-info-fill);
|
||
font-size: 11px;
|
||
line-height: 18px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.description {
|
||
color: var(--dsw-alias-label-tertiary);
|
||
font-size: 14px;
|
||
line-height: 24px;
|
||
font-weight: 400;
|
||
}
|
||
|
||
/* Custom answer row (figma 973:36427): an option-shaped row whose copy is an
|
||
inline text input; focus or a typed draft lifts it to the selected look. */
|
||
.customRow {
|
||
display: flex;
|
||
/* Same first-line alignment as .option — the indicator seat carries the
|
||
2px re-centering margin. */
|
||
align-items: flex-start;
|
||
gap: 8px;
|
||
width: 100%;
|
||
min-height: 40px;
|
||
/* Same reason as .option: the custom row is scroll content, and shrinking
|
||
it pushes the inline input past the footer. */
|
||
flex-shrink: 0;
|
||
padding: 8px 12px 8px 8px;
|
||
border: 1px solid transparent;
|
||
border-radius: 12px;
|
||
transition: background-color 120ms ease, border-color 120ms ease;
|
||
}
|
||
|
||
.customRow:hover,
|
||
.customRow:focus-within,
|
||
.customRowActive {
|
||
background: var(--dsw-alias-interactive-bg-hover);
|
||
}
|
||
|
||
.customRow:focus-within,
|
||
.customRowActive {
|
||
border-color: var(--dsw-alias-border-l2);
|
||
}
|
||
|
||
.customInput {
|
||
flex: 1;
|
||
min-width: 0;
|
||
padding: 0;
|
||
border: none;
|
||
outline: none;
|
||
background: transparent;
|
||
color: var(--dsw-alias-label-primary);
|
||
caret-color: var(--dsw-alias-state-business-primary);
|
||
font: inherit;
|
||
font-size: 14px;
|
||
line-height: 24px;
|
||
}
|
||
|
||
.customInput::placeholder {
|
||
color: var(--dsw-alias-label-caption);
|
||
}
|
||
|
||
/* Optionless question: the free-form answer is the whole body. The 12px side
|
||
margins add to the .options 12px padding so both edges align with the
|
||
title's 24px inset; type matches the option rows, no resize handle. */
|
||
.customTextarea {
|
||
display: block;
|
||
min-height: 64px;
|
||
max-height: 140px;
|
||
flex-shrink: 0;
|
||
margin: 0 12px;
|
||
padding: 8px 12px;
|
||
resize: none;
|
||
border: 1px solid var(--dsw-alias-border-l2);
|
||
border-radius: 10px;
|
||
outline: none;
|
||
background: var(--dsw-alias-bg-module-platform);
|
||
color: var(--dsw-alias-label-primary);
|
||
caret-color: var(--dsw-alias-state-business-primary);
|
||
font: inherit;
|
||
font-size: 14px;
|
||
line-height: 24px;
|
||
}
|
||
|
||
.customTextarea:focus {
|
||
border-color: var(--dsw-alias-state-business-primary);
|
||
}
|
||
|
||
.customTextarea::placeholder {
|
||
color: var(--dsw-alias-label-caption);
|
||
}
|
||
|
||
.footer {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 12px;
|
||
flex-shrink: 0;
|
||
margin-top: 12px;
|
||
padding: 0 10px 0 18px;
|
||
}
|
||
|
||
.feedback {
|
||
flex: 1;
|
||
min-height: 16px;
|
||
color: var(--dsw-alias-state-error-primary);
|
||
font-size: 11px;
|
||
line-height: 16px;
|
||
text-align: right;
|
||
}
|
||
|
||
@media (max-width: 720px) {
|
||
.card {
|
||
border-radius: 16px;
|
||
}
|
||
|
||
.header {
|
||
padding: 10px 12px 0 18px;
|
||
}
|
||
|
||
.options {
|
||
padding: 4px 8px;
|
||
}
|
||
|
||
.title {
|
||
font-size: 15px;
|
||
line-height: 21px;
|
||
}
|
||
|
||
.option,
|
||
.customRow {
|
||
padding: 8px 6px;
|
||
}
|
||
|
||
.footer {
|
||
align-items: flex-end;
|
||
padding: 0 10px;
|
||
}
|
||
|
||
.footerActions {
|
||
flex-shrink: 0;
|
||
}
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.option,
|
||
.customRow {
|
||
transition: none;
|
||
}
|
||
}
|