Files
Project-SDE-WP-Suite/html/theme-light.css
n.siegfried 0cce0b4191 T4.4 - B5: two save indicators, two sentences, neither readable as the other
The app already showed "✓ All changes saved". That badge belongs to the OUTBOX -
it reports whether saved records have reached the project - and it went green
when the queue emptied, whether or not anything in the form had been saved at
all. So the promise B5 says the app does not keep was being made by a component
that could not know whether it was true.

Two indicators now, each speaking for one thing:

  DRAFT   .wp-draft-status, mounted in the creator's sticky save bar and the
          wizard's step navigation. Driven by WPAutosave's status: "No unsaved
          changes" / "Unsaved changes" / "Saving draft…" / "Draft saved at HH:MM"
          / "Draft not saved on this device — <reason>" with a Retry.
  OUTBOX  the existing badge, reworded so every state names the project:
          "Sending N changes to the project…", "Everything sent to the project",
          "N changes not yet sent to the project — retrying", "rejected by the
          project".

"No unsaved changes" rather than "Saved" for an untouched form: those are
different statements and only the first is true before anything is typed. The
component was getting that wrong in the same way the outbox badge was.

Announced per S10 (T4.5's pattern, arriving one task early because this indicator
needs it to exist): role="status" while things are going well, swapping to
role="alert" on failure. A failed autosave means the safety net is not there, and
waiting for a pause in the screen reader's queue to mention that is too late.

The retry button is only rendered in the failed state - a retry offered when
nothing has failed is a button that does nothing.

Styles live in theme-light.css because both form pages mount the same component,
and a second copy in a page sheet is what wave 3 spent itself removing.

VERIFICATION. tests/autosave_check.py grew to 34 checks, all passing. The B5 ones:

  - the indicator reports "No unsaved changes" untouched, then a real save with a
    timestamp, and is visually distinct in each state
  - a simulated storage failure is visually distinct, names the reason, offers a
    retry, and switches to role=alert
  - the sync badge no longer RENDERS "All changes saved", and every state it does
    render names the project

That last check is deliberately scoped to what the badge renders rather than to
the file text: the old phrase still appears in the comment explaining why it was
changed, and asserting on that would be asserting that the reason cannot be
written down.

Note for wave 9: the outbox badge is styled with inline hexes, including #8a6d00
- the ninth amber from BL-009, independently confirming that entry. It is
BL-005's territory, not this task's.

browser_check 71/71.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-15 22:03:16 -05:00

510 lines
21 KiB
CSS

/* IBM Carbon Design System - Light Theme (g10) */
:root {
--cds-interactive-01: #0f62fe;
--cds-interactive-02: #393939;
--cds-interactive-03: #0f62fe;
--cds-interactive-04: #0f62fe;
--cds-ui-background: #f4f4f4;
--cds-ui-01: #ffffff;
--cds-ui-02: #f4f4f4;
--cds-ui-03: #e0e0e0;
--cds-ui-04: #8d8d8d;
--cds-ui-05: #161616;
--cds-text-01: #161616;
--cds-text-02: #525252;
--cds-text-03: #a8a8a8;
--cds-text-04: #ffffff;
--cds-text-05: #6f6f6f;
--cds-text-error: #da1e28;
--cds-icon-01: #161616;
--cds-icon-02: #525252;
--cds-icon-03: #ffffff;
--cds-link-01: #0f62fe;
--cds-link-02: #0043ce;
--cds-inverse-link: #78a9ff;
--cds-field-01: #ffffff;
--cds-field-02: #f4f4f4;
--cds-inverse-01: #ffffff;
--cds-inverse-02: #393939;
--cds-support-01: #da1e28;
--cds-support-02: #198038;
--cds-support-03: #f1c21b;
--cds-support-04: #0043ce;
--cds-inverse-support-01: #fa4d56;
--cds-inverse-support-02: #42be65;
--cds-inverse-support-03: #f1c21b;
--cds-inverse-support-04: #4589ff;
--cds-overlay: rgba(22, 22, 22, .5);
--cds-danger: #da1e28;
--cds-focus: #0f62fe;
--cds-hover-primary: #0353e9;
--cds-active-primary: #002d9c;
--cds-hover-primary-text: #0043ce;
--cds-hover-secondary: #4c4c4c;
--cds-active-secondary: #6f6f6f;
--cds-hover-tertiary: #0353e9;
--cds-active-tertiary: #002d9c;
--cds-hover-ui: #e5e5e5;
--cds-hover-light-ui: #e5e5e5;
--cds-hover-selected-ui: #cacaca;
--cds-active-ui: #c6c6c6;
--cds-active-light-ui: #cacaca;
--cds-selected-ui: #e5e5e5;
--cds-selected-light-ui: #e5e5e5;
--cds-inverse-hover-ui: #353535;
--cds-hover-danger: #ba121b;
--cds-active-danger: #750e13;
--cds-hover-row: #f4f4f4;
--cds-visited-link: #0043ce;
--cds-disabled-01: #f4f4f4;
--cds-disabled-02: #bdbdbd;
--cds-disabled-03: #8d8d8d;
--cds-button-primary: #0f62fe;
--cds-button-secondary: #393939;
--cds-button-tertiary: #0f62fe;
--cds-button-danger-primary: #da1e28;
--cds-button-danger-secondary: #da1e28;
--cds-background: #f4f4f4;
--cds-background-inverse: #161616;
--cds-background-brand: #0f62fe;
--cds-background-active: #e5e5e5;
--cds-background-hover: #e8e8e8;
--cds-background-selected: #e5e5e5;
--cds-background-selected-hover: #cacaca;
--cds-layer: #ffffff;
--cds-layer-accent: #f4f4f4;
--cds-layer-accent-hover: #e8e8e8;
--cds-layer-accent-active: #e0e0e0;
--cds-layer-hover: #e8e8e8;
--cds-layer-active: #e5e5e5;
--cds-layer-selected: #e5e5e5;
--cds-layer-selected-hover: #cacaca;
--cds-layer-selected-inverse: #393939;
--cds-field: #ffffff;
--cds-field-hover: #e8e8e8;
--cds-border-subtle: #e0e0e0;
--cds-border-strong: #8d8d8d;
--cds-border-inverse: #393939;
--cds-border-interactive: #0f62fe;
--cds-border-subtle-selected: #c6c6c6;
--cds-text-primary: #161616;
--cds-text-secondary: #525252;
--cds-text-placeholder: #a8a8a8;
--cds-text-helper: #6f6f6f;
--cds-text-on-color: #ffffff;
--cds-text-inverse: #f4f4f4;
--cds-text-disabled: #bdbdbd;
--cds-link-primary: #0f62fe;
--cds-link-secondary: #0043ce;
--cds-link-visited: #0043ce;
--cds-link-inverse: #78a9ff;
--cds-link-primary-hover: #0353e9;
--cds-icon-primary: #161616;
--cds-icon-secondary: #525252;
--cds-icon-on-color: #ffffff;
--cds-icon-inverse: #f4f4f4;
--cds-icon-disabled: #bdbdbd;
--cds-support-error: #da1e28;
--cds-support-success: #198038;
--cds-support-warning: #f1c21b;
--cds-support-info: #0043ce;
--cds-support-error-inverse: #fa4d56;
--cds-support-success-inverse: #42be65;
--cds-support-warning-inverse: #f1c21b;
--cds-support-info-inverse: #4589ff;
--cds-interactive: #0f62fe;
--cds-shadow: rgba(0, 0, 0, .16);
/* Carbon's own $highlight, which the page sheets each declared for themselves
as --accent-soft / --primary-light / --accent-dim. Real Carbon name and
real Carbon value; this sheet simply never carried it. (T3.2 / S5) */
--cds-highlight: #edf5ff; /* blue-10 */
}
/* ============================================================================
SUITE TOKENS (--wp-*) — roles IBM Carbon does not define
----------------------------------------------------------------------------
Everything above is Carbon g10 and should stay that way. Everything here is a
value the suite invented because Carbon has no slot for it. Keeping the two
namespaces apart is what stops the next person "correcting" #8e6a00 into a
Carbon yellow and breaking the warning banners.
Together with the --cds-* block above, this is the one place a colour,
spacing or type value is defined (CLAUDE.md, "The token rule"). Page
stylesheets alias these; they declare nothing of their own.
Full mapping, and the provenance of every value: docs/reference/tokens.md
============================================================================ */
:root {
/* -- status fills and their text ------------------------------------------
The greens and reds are Carbon 10-step values; the amber pair is not
Carbon at all (Carbon yellow-10 is #fcf4d6). --wp-status-warning-text is
the suite's own accessible amber for text sitting on --wp-status-warning-bg. */
--wp-status-success-bg: #defbe6;
--wp-status-error-bg: #fff1f1;
--wp-status-warning-bg: #fdf6dd;
--wp-status-warning-text: #8e6a00;
/* Four points from --wp-status-warning-text and doing the same job, on the
field view's warn pill. Almost certainly a typo rather than a decision, but
merging it moves a rendered colour, so T3.2 names it and T3.5 merges it.
BL-009 / docs/reference/tokens.md section 8-K. */
--wp-status-warning-text-alt: #8a6d00;
/* Carbon green-70. The value is Carbon, the role is not — Carbon has no
"hover for a green fill", because green is not one of its action colours.
Declared in no sheet today; written raw in five places. */
--wp-hover-success: #0e6027;
/* -- status borders -------------------------------------------------------
Eight values doing four jobs, because two sheets each picked their own.
Every one of them renders somewhere today, so T3.2 names all eight rather
than choosing four winners — choosing is a visual change. T3.5 decides.
See docs/reference/tokens.md section 8-D. */
--wp-status-success-border-a: #a7f0ba; /* green-20, Carbon — console */
--wp-status-success-border-b: #b6e3c6; /* not Carbon — creator */
--wp-status-error-border-a: #ffd7d9; /* red-20, Carbon — console */
--wp-status-error-border-b: #f3c4c4; /* not Carbon — creator, release banner */
--wp-status-error-border-c: #ffc4c4; /* not Carbon — creator, .crit-tag */
--wp-status-warning-border-a: #fddc69; /* yellow-30, Carbon — console */
--wp-status-warning-border-b: #f0d9ad; /* not Carbon — creator */
--wp-accent-border-a: #b9d2fb; /* neither is Carbon blue-20 (#d0e2ff) */
--wp-accent-border-b: #cdd9f2;
/* -- type ------------------------------------------------------------------
Three mono stacks and two sans stacks exist because five sheets each wrote
their own. They are NOT interchangeable: on a machine without IBM Plex Mono
installed — which is most of the target environment — each falls through to
a different face. Unifying them changes what admin and users render, so
T3.2 names all five and T3.5 picks. See docs/reference/tokens.md 6d, 8-H. */
--wp-font-sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
--wp-font-sans-2: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--wp-font-mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', 'Segoe UI Mono', Consolas, monospace;
--wp-font-mono-2: 'IBM Plex Mono', 'Cascadia Mono', Consolas, monospace;
--wp-font-mono-3: 'IBM Plex Mono', ui-monospace, Consolas, monospace;
/* -- spacing ---------------------------------------------------------------
Promoted from console.css, which is the only sheet in the repo whose
spacing is a scale rather than a histogram. The wizard's rem ladder and the
creator's raw px are inventoried in docs/reference/tokens.md 6b and convert
as those pages are rebuilt (T5.x, T7.x) — not here, where any change to a
padding is a visual change. */
--wp-s1: 4px;
--wp-s2: 8px;
--wp-s3: 12px;
--wp-s4: 16px;
--wp-s5: 20px;
--wp-s6: 28px;
/* Control heights: --wp-ctl for anything in a form row, --wp-ctl-sm for
anything inside a table cell. This is what keeps a toolbar one clean band
and a table row ~34px instead of ~100px. */
--wp-ctl: 32px;
--wp-ctl-sm: 26px;
/* -- shape and elevation ---------------------------------------------------
Square corners are the Carbon idiom and the intent everywhere except the
creator, which drifted to 12 different radii (BL-007, owned by T7.1).
The two large shadows share their geometry exactly — 0 4px 16px — and
differ only in tint, so they can be unified later with no layout
consequence. Until then, both are named. */
--wp-radius-0: 0;
--wp-shadow-none: none;
--wp-shadow-lg-neutral: 0 4px 16px rgba(0, 0, 0, .16);
--wp-shadow-lg-cool: 0 4px 16px rgba(20, 30, 50, .12);
/* -- elevation -------------------------------------------------------------
Twelve distinct shadows, which is eleven more than a flat Carbon UI wants.
They are listed rather than merged for the same reason as the borders: each
one renders today and merging is a visual change. That the list is this long
is itself the finding — a later pass can collapse it to two or three now
that they are all visible in one place. */
--wp-shadow-pop: 0 8px 28px rgba(20, 30, 50, .22);
--wp-shadow-menu: 0 8px 24px rgba(20, 30, 50, .18);
--wp-shadow-menu-lg: 0 10px 26px rgba(20, 30, 50, .18);
--wp-shadow-modal: 0 12px 40px rgba(20, 30, 50, .3);
--wp-shadow-modal-lg: 0 20px 60px rgba(0, 0, 0, .3);
--wp-shadow-gate: 0 8px 30px rgba(20, 30, 50, .12);
--wp-shadow-rail: 6px 0 22px rgba(20, 30, 50, .16);
--wp-shadow-drawer: 2px 0 16px rgba(0, 0, 0, .4);
--wp-shadow-sticky: 0 -2px 10px rgba(20, 30, 50, .08);
--wp-shadow-navbar: 0 1px 4px rgba(20, 30, 50, .06);
--wp-shadow-tooltip: 0 4px 14px rgba(20, 30, 50, .22);
--wp-shadow-toast: 0 6px 24px rgba(0, 0, 0, .25);
/* -- scrims ----------------------------------------------------------------
Five overlay fills in three tints. --cds-overlay (rgba(22,22,22,.5)) is the
Carbon one; the drawer's is the same colour 5% darker for no recorded
reason, which makes it the cheapest merge in the set — but still a merge,
so still not here. See docs/reference/tokens.md section 8-F. */
--wp-scrim-drawer: rgba(22, 22, 22, .55);
--wp-scrim-cool: rgba(20, 30, 50, .28);
--wp-scrim-cool-modal: rgba(20, 30, 50, .5);
--wp-scrim-cool-strong: rgba(20, 28, 40, .55);
--wp-scrim-neutral: rgba(0, 0, 0, .5);
--wp-scrim-loading: rgba(244, 245, 247, .82);
--wp-scrim-frosted: rgba(255, 255, 255, .94); /* sticky section-nav backdrop */
--wp-on-accent-divider: rgba(255, 255, 255, .28);
/* -- surfaces that are not Carbon greys ------------------------------------
Four neutrals the suite invented, all within a few points of a Carbon step
and none of them equal to one. --wp-table-zebra is the dangerous one: it is
six points from --cds-layer-accent, and collapsing them erases the striping
on the nine-column user table. Section 8-A. */
--wp-table-zebra: #fafafa;
--wp-table-row-hover: #eef0f2;
--wp-nav-bg: #fbfbfc;
--wp-nav-hover: #eef0f3;
--wp-nav-active: #e8eaed;
--wp-pop-divider: #f0f0f0; /* popover hairlines in the shared chrome */
--wp-accent-soft-hover: #e2ecfc; /* hover on an --cds-highlight fill */
/* -- the Project Super User tag --------------------------------------------
Carbon purple-10 / purple-60. Real Carbon values with no --cds-* slot in
the subset this sheet carries. One consumer; promote into --cds-* if a
second ever appears. */
--wp-tag-super-bg: #e8daff;
--wp-tag-super-text: #6929c4;
/* -- console output --------------------------------------------------------
pre.out is a terminal emulator, not product surface. Green-on-dark pass and
red-on-dark fail is the convention being quoted; it should not track the
palette and must not be "corrected" to Carbon's support colours. */
--wp-term-bg: #0f1525;
--wp-term-fg: #d7e0f5;
--wp-term-pass: #56d364;
--wp-term-fail: #ff7b72;
/* -- dev mode --------------------------------------------------------------
Deliberately outside the palette. The banner is MEANT to look wrong; giving
it the product's amber would make it look intentional, which defeats it. */
--wp-dev-bg: #3a2a00;
--wp-dev-fg: #ffd479;
--wp-dev-rule: #ffb000;
/* -- button roles (A5) -----------------------------------------------------
Four roles and no fifth. Every button in the app is one of them, and the
class-to-role mapping is in docs/reference/tokens.md section 12.
primary the one action this screen exists for. Filled accent. At most one
per view.
secondary every other real action. White fill, --border-strong hairline,
accent on hover. This is the app's workhorse.
tertiary navigational or undoing. No fill, no border, accent text.
danger destructive. Outlined red by default; filled red only where the
control is small enough that an outline would not read (the ✕ on
a sequence row).
GREEN IS A STATUS COLOUR AND NEVER FILLS A BUTTON. It says cleared, ready,
complete — on a dot, a pill, a banner, a badge. Two buttons broke that rule
and are what A5 recorded: "SOP Complete" and "Save & View" shouted louder
than every other action in the suite while doing nothing more dangerous than
saving. They are primary now. The green did not go anywhere: the launcher
card still turns green when its SOP completes, on the border and the status
line, which is where a status belongs.
No value here is new — these are the fills the sheets already rendered,
given one definition so that "primary" means one thing. */
--wp-btn-primary-bg: var(--cds-interactive-01);
--wp-btn-primary-fg: var(--cds-text-on-color);
--wp-btn-primary-hover: var(--cds-hover-primary);
--wp-btn-primary-active: var(--cds-active-primary);
--wp-btn-secondary-bg: var(--cds-field);
--wp-btn-secondary-fg: var(--cds-text-primary);
--wp-btn-secondary-border: var(--cds-border-strong);
--wp-btn-secondary-hover-fg: var(--cds-interactive-01);
--wp-btn-tertiary-fg: var(--cds-interactive-01);
--wp-btn-tertiary-hover-fg: var(--cds-hover-primary-text);
--wp-btn-danger-fg: var(--cds-support-error);
--wp-btn-danger-border: var(--cds-support-error);
--wp-btn-danger-soft-bg: var(--wp-status-error-bg);
--wp-btn-danger-fill-bg: var(--cds-support-error);
--wp-btn-danger-fill-fg: var(--cds-text-on-color);
/* -- the second blue -------------------------------------------------------
#2563d6, not #0f62fe. Fills .sop-inherited — every field a work package
inherited from its SOP — at 7% alpha, which is why nobody has noticed a
second brand blue. Named here so it is visible; swapped at T3.5 (BL-008). */
--wp-sop-inherited-bg: rgba(37, 99, 214, .07);
}
/* Typography */
body {
font-family: var(--wp-font-sans);
color: var(--cds-text-primary);
background: var(--cds-background);
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
}
h1, h2, h3, h4, h5, h6 {
font-weight: 600;
line-height: 1.28572;
}
h1 { font-size: 2rem; }
h2 { font-size: 1.75rem; }
h3 { font-size: 1.25rem; }
h4 { font-size: 1rem; }
h5 { font-size: .875rem; }
h6 { font-size: .75rem; }
a {
color: var(--cds-link-primary);
text-decoration: none;
}
a:hover {
color: var(--cds-link-primary-hover);
text-decoration: underline;
}
button {
font-family: inherit;
cursor: pointer;
}
input, textarea, select {
font-family: inherit;
color: var(--cds-text-primary);
}
/* ============================================================================
App shell — shared "UI Shell" chrome (Prime Controls, IBM Carbon styling)
----------------------------------------------------------------------------
One dark top bar across every page so the suite reads as a single product.
The Prime Controls logo is a white-background wordmark, so it sits inside a
white "chip" on the near-black bar (reads as intentional, not a stray box).
Flip --wp-appbar-bg to a light value if a light header is ever preferred.
============================================================================ */
:root {
--wp-appbar-bg: #161616; /* near-black UI Shell bar */
--wp-appbar-fg: #ffffff;
--wp-appbar-fg-dim: #c6c6c6;
--wp-appbar-border: #6f6f6f; /* outline for ghost buttons on the bar */
--wp-appbar-hover: #353535;
--wp-appbar-height: 48px;
/* Carbon gray-90 — one step up from the bar itself. The raised surfaces that
sit ON the dark bar or the drawer: the chrome's search field, the drawer's
current row. Its two consumers both hardcoded it before T3.2. */
--wp-appbar-layer: #262626;
}
.wp-appbar {
background: var(--wp-appbar-bg);
color: var(--wp-appbar-fg);
display: flex;
align-items: center;
gap: 16px;
height: var(--wp-appbar-height);
padding: 0 16px;
position: sticky;
top: 0;
z-index: 100;
}
.wp-appbar-brand {
display: flex;
align-items: center;
gap: 12px;
height: 100%;
text-decoration: none;
color: var(--wp-appbar-fg);
}
.wp-appbar-brand:hover { text-decoration: none; opacity: .92; }
.wp-logo-chip {
display: inline-flex;
align-items: center;
justify-content: center;
background: var(--cds-ui-01);
border-radius: 4px;
padding: 4px 8px;
}
.wp-logo-chip img { height: 24px; width: auto; display: block; }
.wp-appbar-title {
font-size: 15px;
font-weight: 600;
color: var(--wp-appbar-fg);
white-space: nowrap;
letter-spacing: .01em;
}
.wp-appbar-title .wp-appbar-sub { font-weight: 400; color: var(--wp-appbar-fg-dim); }
.wp-appbar-spacer { flex: 1 1 auto; }
.wp-appbar-meta { font-size: 13px; color: var(--wp-appbar-fg-dim); white-space: nowrap; }
.wp-appbar-actions { display: flex; align-items: center; gap: 8px; }
/* Buttons and links that live on the dark bar */
.wp-appbar-btn {
background: transparent;
color: var(--wp-appbar-fg);
border: 1px solid var(--wp-appbar-border);
border-radius: 0;
padding: 7px 14px;
font-size: 14px;
font-family: inherit;
line-height: 1.2;
cursor: pointer;
text-decoration: none;
white-space: nowrap;
transition: background .15s, border-color .15s;
}
.wp-appbar-btn:hover { background: var(--wp-appbar-hover); color: var(--wp-appbar-fg); text-decoration: none; }
.wp-appbar-btn.primary { background: var(--cds-interactive-01); border-color: var(--cds-interactive-01); }
.wp-appbar-btn.primary:hover { background: var(--cds-hover-primary); border-color: var(--cds-hover-primary); }
.wp-appbar-btn:focus-visible { outline: 2px solid var(--wp-appbar-fg); outline-offset: 1px; }
.wp-appbar-count { font-size: 13px; color: var(--wp-appbar-fg-dim); padding: 0 2px; white-space: nowrap; }
/* Plain text links on the dark bar (Overview / Feedback / Help, Admin, etc.) */
.wp-appbar-link { color: var(--wp-appbar-fg-dim); text-decoration: none; font-size: 14px; white-space: nowrap; }
.wp-appbar-link:hover { color: var(--wp-appbar-fg); text-decoration: none; }
@media (max-width: 720px) {
.wp-appbar { height: auto; flex-wrap: wrap; gap: 8px; padding: 8px 12px; }
.wp-appbar-actions { flex-wrap: wrap; }
.wp-appbar-meta { width: 100%; order: 5; }
}
/* ============================================================================
DRAFT STATE INDICATOR (B5 / T4.4)
----------------------------------------------------------------------------
Reports the DRAFT — what wp-autosave.js is holding for you on this device.
The sync badge in project-data.js reports the OUTBOX, which is a different
question ("has the saved record reached the project"), and its wording now
says so. Two indicators, two sentences, neither readable as the other.
Lives in theme-light.css because both form pages mount the same component,
and a second copy in a page sheet is what wave 3 spent itself removing.
============================================================================ */
.wp-draft-status {
display: inline-flex;
align-items: center;
gap: 8px;
font-size: 12px;
font-weight: 400;
line-height: 1.3;
color: var(--cds-text-secondary);
white-space: nowrap;
}
.wp-draft-status.is-saved { color: var(--cds-support-success); font-weight: 600; }
.wp-draft-status.is-saving { color: var(--cds-text-secondary); }
/* A failed autosave is not a quieter version of a successful one — it means the
safety net is not there. Red, bold, and it keeps its retry. */
.wp-draft-status.is-failed {
color: var(--cds-support-error);
font-weight: 600;
white-space: normal;
}
.wp-draft-retry {
font: inherit;
font-size: 11px;
font-weight: 600;
padding: 2px 9px;
cursor: pointer;
background: var(--wp-btn-secondary-bg);
color: var(--wp-btn-danger-fg);
border: 1px solid var(--wp-btn-danger-border);
border-radius: var(--wp-radius-0);
}
.wp-draft-retry:hover { background: var(--wp-btn-danger-soft-bg); }
.wp-draft-retry:focus-visible { outline: 2px solid var(--cds-focus); outline-offset: -2px; }