* { box-sizing: border-box; }
    :root { color-scheme: light; }
    html, body { margin: 0; padding: 0; color-scheme: light; }
    body { background: #1c1f26; font-family: var(--font-sans); -webkit-font-smoothing: antialiased; }
    button { font-family: inherit; }
    input, textarea, select { font-family: inherit; color: #0E1726; background-color: #ffffff; }
    input::placeholder, textarea::placeholder { color: #454C5C; }
    option { color: #0E1726; background-color: #ffffff; }
    ::-webkit-scrollbar { width: 9px; height: 9px; }
    ::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.18); border-radius: 99px; }
    ::-webkit-scrollbar-track { background: transparent; }
    @keyframes hc-spin { to { transform: rotate(360deg); } }
    @keyframes hc-fadeup { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
    /* The mirror of hc-fadeup, for a menu that opens above its field instead of
       below it. A menu always grows out of the control it belongs to. */
    @keyframes hc-fadedown { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }
    @keyframes hc-fade { from { opacity: 0; } to { opacity: 1; } }
    /* The Manage window's entry, for when it opens centred.
       It cannot use hc-fadeup: that keyframe ends at `transform: none`, which
       wipes the translate(-50%, -50%) doing the centring for the whole 220ms.
       The window rendered half its own size down and right of centre and then
       snapped into place when the animation finished, which read as the window
       opening in the wrong spot and correcting itself. Carrying the centring
       through both ends of the keyframe is the fix. */
    @keyframes hc-win-in {
      from { opacity: 0; transform: translate(-50%, -50%) scale(0.985); }
      to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
    }
    @keyframes hc-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.25; } }
    @keyframes hc-pop { 0% { transform: scale(0.6); opacity: 0; } 60% { transform: scale(1.08); } 100% { transform: scale(1); opacity: 1; } }
    @keyframes hc-slidein { from { opacity: 0; transform: translateX(-8px); } to { opacity: 1; transform: none; } }
    @keyframes hc-slide-in { from { opacity: 0; transform: translateX(26px); } to { opacity: 1; transform: none; } }
    @keyframes hc-rank { 0% { transform: translateY(6px) scale(0.96); } 100% { transform: none; } }
    @keyframes hc-sqfill { from { width: 4%; } to { width: 92%; } }
    /* A band travelling across a chart while its data is being read. Motion
       on the thing being rebuilt, so the wait happens where you are looking. */
    @keyframes hc-sweep { from { transform: translateX(-60%); } to { transform: translateX(260%); } }
    @keyframes hc-flicker { 0%,100% { box-shadow: 0 0 0 0 currentColor; } 50% { box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 40%, transparent); } }
    @keyframes hc-ping { 0% { transform: scale(1); opacity: 0.5; } 80%, 100% { transform: scale(2.2); opacity: 0; } }
    @keyframes hc-nudge { 0%, 100% { transform: rotate(0deg); } 25% { transform: rotate(-9deg); } 60% { transform: rotate(7deg); } }
    /* The check a finding was traced to. Holds long enough to be found by eye,
       then clears so the row reads like every other row. */
    @keyframes hc-trace { 0%, 55% { background: #EEF1F7; } 100% { background: transparent; } }
    @keyframes hc-breathe { 0%, 100% { box-shadow: 0 12px 30px rgba(36,61,102,0.30), 0 0 0 0 rgba(36,61,102,0.22); } 50% { box-shadow: 0 14px 34px rgba(36,61,102,0.42), 0 0 0 12px rgba(36,61,102,0); } }
    /* Skeleton, the app's first. Used while a dropped file is being read, so
       the shape of the table arrives before its contents do. The sweep is a
       background-position move, which stays off the main thread - never
       animate width here. Reduced motion drops to a flat fill, handled by the
       global rule below plus the explicit background reset. */
    /* Editable table cells.
       Airtable, Notion and Linear show nothing at rest and reveal on hover,
       which is right for a grid a power user lives in. This table is watched
       for five seconds by somebody who has never seen it, so it needs to say
       "you can change this" before anyone moves the mouse. The compromise is a
       faint fill and an underline - it reads as a field without putting a box
       round every cell, which is the thing every design system warns against. */
    .hc-cell { border: 1px solid transparent; background: #FAFAFC; box-shadow: inset 0 -1px 0 #DCDCE4; transition: background 120ms ease-out, border-color 120ms ease-out, box-shadow 120ms ease-out; }
    .hc-cell:hover { background: #F1F0F8; border-color: #E2E1EA; box-shadow: none; }
    .hc-cell:focus-visible { outline: none; border-color: #243D66; background: #fff; box-shadow: 0 0 0 3px rgba(36,61,102,0.16); }
    .hc-cell.is-bad { border-color: #F1DCAE; background: #FEF8EC; box-shadow: inset 0 -1px 0 #E8CE93; }
    .hc-cell.is-bad:hover { background: #FDF3DF; box-shadow: none; }
    .hc-cell.is-edited { background: #EEF1F7; border-color: #C2CFE4; box-shadow: none; }
    /* The issues table wants the same behaviour with nothing at rest. Eight rows
       of filled cells put a box round every value and the table stopped reading
       as a list of findings. Reveal on hover instead - Airtable and Notion are
       right about this once the grid is more than three rows deep. is-edited
       still shows, because a value that no longer matches the scan has to be
       visible without hovering it. */
    .hc-icell { border: 1px solid transparent; background: transparent; box-shadow: none; transition: background 120ms ease-out, border-color 120ms ease-out, box-shadow 120ms ease-out; }
    .hc-icell:hover { background: #F1F0F8; border-color: #E2E1EA; }
    .hc-icell:focus-visible { outline: none; border-color: #243D66; background: #fff; box-shadow: 0 0 0 3px rgba(36,61,102,0.16); }
    .hc-icell.is-edited { background: #EEF1F7; border-color: #C2CFE4; }
    .hc-icell.is-edited:hover { background: #FDE7DF; }
    /* The remove button on a row. Quiet until the row is under the pointer, so
       twelve of them do not shout at you. */
    .hc-rowx { background: transparent; opacity: 0.35; transition: opacity 120ms ease-out, color 120ms ease-out, background 120ms ease-out; }
    .hc-rowx:hover { opacity: 1; color: #C72E0C; background: #FDEBE6; }
    .hc-rowx:focus-visible { opacity: 1; outline: none; box-shadow: 0 0 0 3px rgba(36,61,102,0.16); }
    .hc-addrow { transition: border-color 120ms ease-out, background 120ms ease-out, color 120ms ease-out; }
    .hc-addrow:hover { border-color: #243D66; background: #EEF1F7; color: #0E1726; }
    .hc-addrow:focus-visible { outline: none; border-color: #243D66; box-shadow: 0 0 0 3px rgba(36,61,102,0.16); }
    /* The sign-off toggle is a yes/no, so it reads as a control, not a field. */
    .hc-toggle { transition: background 120ms ease-out, border-color 120ms ease-out; }
    .hc-toggle:hover { background: #F1F0F8; border-color: #C9C9D4; }
    .hc-toggle:focus-visible { outline: none; border-color: #243D66; box-shadow: 0 0 0 3px rgba(36,61,102,0.16); }
    /* type="search" is right for the QA Library box - it announces as a search
       field - but WebKit then draws its own clear button next to the one the
       component already renders, so the field ends up with two X's. This is
       the only way to remove it: a pseudo-element cannot be styled inline. */
    .hc-search-field::-webkit-search-cancel-button,
    .hc-search-field::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }
    @keyframes hc-shimmer { from { background-position: 100% 50%; } to { background-position: 0 50%; } }
    .hc-skel { background: linear-gradient(90deg, #EFEFF4 25%, #F7F7FA 37%, #EFEFF4 63%); background-size: 400% 100%; animation: hc-shimmer 1.4s ease infinite; border-radius: 5px; }
    @media (prefers-reduced-motion: reduce) { .hc-skel { animation: none !important; background: #EFEFF4; } }
    @property --hc-ai-angle { syntax: "<angle>"; initial-value: 0deg; inherits: false; }
    @keyframes hc-ai-sweep { to { --hc-ai-angle: 360deg; } }
    .hc-ai-btn { border: 1px solid transparent; background: linear-gradient(#EEF1F7, #EEF1F7) padding-box, conic-gradient(from var(--hc-ai-angle), #243D66, #2E4B85, #C2CFE4, #243D66) border-box; transition: transform 140ms cubic-bezier(0.22,1,0.36,1), box-shadow 140ms cubic-bezier(0.22,1,0.36,1); }
    .hc-ai-btn.is-open { background: linear-gradient(#243D66, #243D66) padding-box, conic-gradient(from var(--hc-ai-angle), #243D66, #2E4B85, #C2CFE4, #243D66) border-box; }
    .hc-ai-btn:hover { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(36,61,102,0.22); animation: hc-ai-sweep 2.4s linear infinite; }
    .hc-ai-btn:active { transform: translateY(0); }
    .hc-ai-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(36,61,102,0.30); }
    .hc-press { transition: transform 90ms cubic-bezier(0.22,1,0.36,1); }
    .hc-press:active { transform: scale(0.98); }
    .hc-ai-spark { transition: transform 180ms cubic-bezier(0.22,1,0.36,1); }
    .hc-ai-btn:hover .hc-ai-spark { transform: rotate(12deg) scale(1.08); }
    .hc-ai-launcher { box-shadow: 0 12px 30px rgba(36,61,102,0.30); animation: hc-breathe 4.5s ease-in-out infinite; transition: transform 140ms cubic-bezier(0.22,1,0.36,1); }
    .hc-ai-launcher:hover { transform: scale(1.06); }
    .hc-ai-launcher:active { transform: scale(0.96); }
    .hc-ai-launcher:focus-visible { outline: none; box-shadow: 0 12px 30px rgba(36,61,102,0.30), 0 0 0 3px rgba(36,61,102,0.30); }
    @media (prefers-reduced-motion: reduce) { * { animation-duration: .01ms !important; transition-duration: .01ms !important; } }
    /* Notifications. The badge pops once when a new item lands, so a prospect
       sees it arrive. hc-collapse is the exit for a row leaving a filtered
       list - an accelerate curve, because reusing the entrance curve on an
       exit is the one thing the Material guidance names outright. The global
       prefers-reduced-motion rule above already neutralises both. */
    @keyframes hc-badge-pop { 0% { transform: scale(0.4); opacity: 0; } 60% { transform: scale(1.18); opacity: 1; } 100% { transform: scale(1); } }
    @keyframes hc-collapse { from { opacity: 1; max-height: 90px; } to { opacity: 0; max-height: 0; } }
    /* Lean issues table: a row with a new reply. The highlighter stroke draws
       left to right once, then a soft glow breathes until the row is opened.
       The global reduced-motion rule above stills both. */
    @keyframes hc-act-stroke { from { transform: scaleX(0); opacity: 0.4; } to { transform: scaleX(1); opacity: 1; } }
    @keyframes hc-act-glow { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
    /* The bell rings while something is unread, and stops when it is clicked.
       A swing, not a wobble: transform-origin sits at the crown so the body
       pivots the way a real bell does. Most of the cycle is stillness - it
       rings for about a second, then rests, which reads as a bell rather than
       as a broken element vibrating in the corner of a sales call. */
    @keyframes hc-ring {
      0%   { transform: rotate(0deg); }
      3%   { transform: rotate(14deg); }
      9%   { transform: rotate(-12deg); }
      15%  { transform: rotate(9deg); }
      21%  { transform: rotate(-7deg); }
      27%  { transform: rotate(4deg); }
      33%  { transform: rotate(-2deg); }
      38%, 100% { transform: rotate(0deg); }
    }
    .hc-bell-ring { transform-origin: 50% 15%; animation: hc-ring 2.8s ease-in-out infinite; }
    @media (prefers-reduced-motion: reduce) { .hc-bell-ring { animation: none !important; } }
    .hc-badge-pop { animation: hc-badge-pop 120ms cubic-bezier(0.4,0,0.2,1); }
    .hc-notif-bell:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(36,61,102,0.30); }
    /* The figure card's minimise button (2026-10-21): the house hover and focus ring. */
    .hc-figcard-toggle:hover { background: rgba(36,61,102,0.08) !important; }
    .hc-figcard-toggle:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(36,61,102,0.30); }
    @media (prefers-reduced-motion: reduce) { .hc-ping-ring { animation: none !important; } }
    @media (prefers-reduced-motion: reduce) { .hc-ai-launcher { animation: none !important; } .hc-ai-btn:hover { animation: none !important; } }
