/* =============================================================================
 * Huly "Clay" -- claymorphism / soft 3D theme overlay.
 *
 * Purely cosmetic: colors, radii, shadows, spacing, motion. Nothing here hides,
 * moves or disables a control, so behaviour stays exactly the stock front's.
 *
 * Injected into index.html by the compose nginx (see .huly.nginx), NOT compiled
 * into the front image -- a theme change is `docker compose restart nginx`,
 * not a 525MB image rebuild and the deploy-service.sh round trip.
 *
 * Two override mechanisms, in order of preference:
 *
 *   1. Design tokens. Huly defines its radius/spacing/shadow scale on the
 *      universal selector (`*{--small-BorderRadius: .375rem; ...}`) and its
 *      palette on `.theme-dark` / `.theme-light`. Retuning those reaches every
 *      component at once, including screens not inspected here. Palette
 *      overrides need no !important (`html.theme-dark` outranks `.theme-dark`);
 *      the `*`-defined scale does, since `*` re-declares it on every element.
 *
 *   2. Per-component rules, forced. The front ships its CSS inside the JS
 *      bundle and style-loader injects ~600 <style> tags into <head> at
 *      runtime, after this file -- source order can never win.
 *
 * Selectors use only stable platform class names (antiXxx / hulyXxx / kebab).
 * Svelte scope classes (.svelte-25dft9) are per-build hashes -- never target
 * them; they change on every front rebuild.
 * ========================================================================== */

/* -----------------------------------------------------------------------------
 * 1. Shape and elevation scale
 *
 * Radii are bumped one step up Huly's own ladder rather than replaced, so the
 * relative hierarchy the components were designed against still holds. Capped
 * at 18px: past that a dense work tool starts reading as a children's app,
 * which is the failure mode of claymorphism.
 * -------------------------------------------------------------------------- */

* {
  --min-BorderRadius: .25rem !important;             /* 2  -> 4px  */
  --extra-small-BorderRadius: .4375rem !important;   /* 4  -> 7px  */
  --extra-small-focus-BorderRadius: .5625rem !important;
  --small-BorderRadius: .625rem !important;          /* 6  -> 10px */
  --small-focus-BorderRadius: .75rem !important;
  --medium-BorderRadius: .75rem !important;          /* 8  -> 12px */
  --medium-focus-BorderRadius: .875rem !important;
  --large-BorderRadius: 1.25rem !important;          /* 16 -> 20px */
  --large-focus-BorderRadius: 1.375rem !important;

  /* Popover/modal shadows: wider and softer, cast further down. A clay object
     sits *on* something; a tight even blur reads as a sticker. */
  --global-popover-ShadowBlur: 2rem !important;
  --global-popover-ShadowY: .875rem !important;
  --global-modal-ShadowBlur: 3.5rem !important;
  --global-modal-ShadowY: 2rem !important;
}

html {
  --clay-r-xs: .4375rem;  /*  7px -- chips, tags, tiny markers        */
  --clay-r-sm: .625rem;   /* 10px -- inputs, small controls           */
  --clay-r-md: .75rem;    /* 12px -- buttons, nav items, rows         */
  --clay-r-lg: 1rem;      /* 16px -- cards, popups, list containers   */
  --clay-r-xl: 1.25rem;   /* 20px -- panels, modals, the main slabs   */

  --clay-ease: cubic-bezier(.2, .8, .3, 1);
  --clay-fast: 140ms var(--clay-ease);
  --clay-slow: 260ms var(--clay-ease);

  /* Gap between the shell slabs and the canvas they float on. */
  --clay-gap: .625rem;
}

/* -----------------------------------------------------------------------------
 * 2. Palette -- dark
 *
 * The one structural change: stock Huly used #161719 for BOTH the page
 * background and the panels on it, so the whole shell was optically flat.
 * Everything below depends on the canvas receding behind its content.
 * -------------------------------------------------------------------------- */

html.theme-dark {
  --theme-back-color: #0C0D10;          /* canvas, furthest back      */
  --theme-bg-color: #121317;
  --theme-statusbar-color: #0C0D10;
  --theme-navpanel-color: #131519;      /* navigator slab             */
  --theme-panel-color: #16181D;         /* content slab               */
  --theme-comp-header-color: #1A1D22;
  --theme-bg-divider-color: #1E2128;
  --theme-overlay-color: rgba(6, 8, 12, .55);

  --theme-popup-color: #1D2027;
  --theme-popup-trans-color: #1D2027ee;
  --theme-popup-trans-gradient: linear-gradient(to bottom, #1D2027ff, #1D202700);
  --theme-popup-header: #262A33;
  --theme-popup-hover: #2A2F39;
  --theme-popup-divider: rgba(165, 189, 255, .09);
  --theme-popup-deactivated: #16181D;

  --theme-list-row-color: #1B1E24;
  --theme-list-subheader-color: #191C21;
  --theme-list-button-color: #22262E;
  --theme-list-button-hover: #292E38;
  --theme-link-button-color: #22262E;
  --theme-link-button-hover: #292E38;
  --theme-table-header-color: #181A1F;
  --theme-table-row-color: #1B1E24;
  --theme-button-container-color: #1E2128;

  /* Hairlines carry a trace of the accent hue instead of neutral white --
     a warm-neutral surface separated by a cold line looks dirty. */
  --theme-divider-color: rgba(165, 189, 255, .07);
  --theme-navpanel-divider: rgba(165, 189, 255, .08);
  --theme-navpanel-border: rgba(165, 189, 255, .07);
  --theme-list-divider-color: rgba(165, 189, 255, .07);
  --theme-list-border-color: rgba(165, 189, 255, .05);
  --theme-table-border-color: rgba(165, 189, 255, .08);
  --theme-button-border: rgba(165, 189, 255, .10);
  --theme-refinput-border: rgba(165, 189, 255, .10);
  --theme-refinput-divider: rgba(165, 189, 255, .07);

  --theme-navpanel-hovered: rgba(165, 189, 255, .055);
  --theme-navpanel-selected: rgba(165, 189, 255, .10);
  --theme-button-default: rgba(165, 189, 255, .045);
  --theme-button-hovered: rgba(165, 189, 255, .085);
  --theme-button-pressed: rgba(165, 189, 255, .13);
  --theme-button-focused: rgba(165, 189, 255, .085);
  --theme-button-focused-border: rgba(165, 189, 255, .14);

  --theme-kanban-card-bg-color: #1C1F26;
  --theme-kanban-card-border: rgba(165, 189, 255, .07);
  --theme-kanban-card-footer: rgba(165, 189, 255, .05);

  --theme-content-color: rgba(233, 238, 248, .84);
  --theme-dark-color: rgba(233, 238, 248, .62);
  --theme-halfcontent-color: rgba(233, 238, 248, .50);
  --theme-darker-color: rgba(233, 238, 248, .42);
  --theme-caption-color: #F4F7FC;
  --theme-link-color: #6E9BFF;
  --theme-editbox-focus-color: rgba(165, 189, 255, .05);
  --theme-editbox-focus-border: #4E7FE8;
  --theme-tooltip-bg: #262A33;

  --global-surface-01-BackgroundColor: #131519;
  --global-surface-01-hover-BackgroundColor: #191C21;
  --global-surface-02-BackgroundColor: #16181D;
  --global-surface-01-BorderColor: rgba(165, 189, 255, .08);
  --global-surface-02-BorderColor: rgba(165, 189, 255, .08);
  --global-popover-BackgroundColor: #1D2027;
  --global-popover-hover-BackgroundColor: #2A2F39;
  --global-popover-BorderColor: rgba(165, 189, 255, .10);
  --global-ui-BorderColor: rgba(165, 189, 255, .10);
  --global-ui-hover-BackgroundColor: rgba(165, 189, 255, .10);
  --global-ui-active-BackgroundColor: rgba(165, 189, 255, .16);
  --global-popover-ShadowColor: rgba(0, 0, 0, .55);
  --global-modal-ShadowColor: rgba(0, 0, 0, .62);

  /* Elevation: three steps, no more. A flat hierarchy is what keeps soft 3D
     from turning into a pile of floating toys. Shadows are tinted with the
     canvas ink rather than pure black -- neutral black over a blue-grey
     surface reads as grime. */
  --clay-shadow-1:
    0 1px 2px rgba(4, 6, 12, .34),
    0 6px 14px -6px rgba(4, 6, 12, .42);
  --clay-shadow-2:
    0 2px 5px rgba(4, 6, 12, .36),
    0 18px 34px -14px rgba(4, 6, 12, .55);
  --clay-shadow-3:
    0 5px 12px rgba(4, 6, 12, .38),
    0 40px 72px -30px rgba(4, 6, 12, .72);

  /* The rims are the actual "clay". A lit top edge and a shaded bottom one turn
     a rectangle into a moulded slab -- and they have to be *blurred*, not
     hairlines: a crisp 1px line reads as a border, a 2-3px falloff reads as a
     rounded wall catching the light. This is the single biggest difference
     between claymorphism and "flat with rounded corners". */
  --clay-lit:
    inset 0 2px 1px -1px rgba(255, 255, 255, .10),
    inset 0 1px 3px -1px rgba(255, 255, 255, .06);
  --clay-shade: inset 0 -3px 5px -3px rgba(0, 0, 0, .55);
  --clay-press:
    inset 0 2px 6px rgba(0, 0, 0, .45),
    inset 0 -1px 0 rgba(255, 255, 255, .04);
  --clay-ring: 0 0 0 3px rgba(78, 127, 232, .32);

  /* Top-lit vertical falloff. Painted as a background layer over the surface
     colour, it is what gives a slab volume instead of just an edge. */
  --clay-sheen: linear-gradient(180deg, rgba(255, 255, 255, .055), rgba(255, 255, 255, 0) 58%);
  /* Same idea for the big slabs, but with an absolute stop: a percentage
     falloff on an 800px panel washes half the screen instead of catching an
     edge. */
  --clay-sheen-slab: linear-gradient(180deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, 0) 130px);
  --clay-glow: radial-gradient(1100px 520px at 18% -12%, rgba(110, 155, 255, .07), transparent 62%);

  /* Every component that reads --theme-popup-shadow (antiCard, antiPanel and
     each scoped popup) inherits the clay elevation from this one line. */
  --theme-popup-shadow: var(--clay-shadow-3), var(--clay-lit);
}

/* -----------------------------------------------------------------------------
 * 3. Palette -- light
 *
 * Light claymorphism needs a tinted, slightly grey canvas: pure white behind
 * white cards leaves shadows nothing to fall on.
 * -------------------------------------------------------------------------- */

html.theme-light {
  --theme-back-color: #E7EAF1;
  --theme-bg-color: #EDF0F6;
  --theme-statusbar-color: #E7EAF1;
  --theme-navpanel-color: #F4F6FA;
  --theme-panel-color: #FFFFFF;
  --theme-comp-header-color: #FBFCFE;
  --theme-bg-divider-color: #DFE3EC;
  --theme-overlay-color: rgba(23, 32, 56, .22);

  --theme-popup-color: #FFFFFF;
  --theme-popup-trans-color: #FFFFFFee;
  --theme-popup-header: #F1F4F9;
  --theme-popup-hover: #EDF1F8;
  --theme-popup-divider: rgba(23, 32, 56, .07);
  --theme-popup-deactivated: #DDE2EC;

  --theme-list-row-color: #FFFFFF;
  --theme-list-subheader-color: #F2F4F9;
  --theme-list-button-color: #F1F4F9;
  --theme-list-button-hover: #E8ECF5;
  --theme-link-button-color: #EDF1F8;
  --theme-link-button-hover: #E3E9F4;
  --theme-table-header-color: #F2F4F9;
  --theme-table-row-color: #FFFFFF;
  --theme-button-container-color: #EBEFF6;

  --theme-divider-color: rgba(23, 32, 56, .07);
  --theme-navpanel-divider: rgba(23, 32, 56, .08);
  --theme-navpanel-border: rgba(23, 32, 56, .06);
  --theme-list-divider-color: rgba(23, 32, 56, .07);
  --theme-list-border-color: rgba(23, 32, 56, .06);
  --theme-table-border-color: rgba(23, 32, 56, .08);
  --theme-button-border: rgba(23, 32, 56, .10);
  --theme-refinput-border: rgba(23, 32, 56, .10);
  --theme-refinput-divider: rgba(23, 32, 56, .07);

  --theme-navpanel-hovered: rgba(23, 32, 56, .045);
  --theme-navpanel-selected: rgba(23, 32, 56, .08);
  --theme-button-default: rgba(255, 255, 255, .75);
  --theme-button-hovered: rgba(23, 32, 56, .05);
  --theme-button-pressed: rgba(23, 32, 56, .09);
  --theme-button-focused: rgba(23, 32, 56, .06);

  --theme-kanban-card-bg-color: #FFFFFF;
  --theme-kanban-card-border: rgba(23, 32, 56, .06);
  --theme-kanban-card-footer: rgba(23, 32, 56, .04);

  --theme-content-color: rgba(17, 24, 42, .82);
  --theme-dark-color: rgba(17, 24, 42, .60);
  --theme-halfcontent-color: rgba(17, 24, 42, .50);
  --theme-darker-color: rgba(17, 24, 42, .42);
  --theme-caption-color: #0E1424;
  --theme-link-color: #2B62D9;
  --theme-tooltip-bg: #2A303C;

  --global-surface-01-BackgroundColor: #F4F6FA;
  --global-surface-01-hover-BackgroundColor: #EDF0F6;
  --global-surface-02-BackgroundColor: #FFFFFF;
  --global-surface-01-BorderColor: rgba(23, 32, 56, .08);
  --global-surface-02-BorderColor: rgba(23, 32, 56, .07);
  --global-ui-BorderColor: rgba(23, 32, 56, .10);
  --global-popover-ShadowColor: rgba(20, 30, 55, .18);
  --global-modal-ShadowColor: rgba(20, 30, 55, .24);

  --clay-shadow-1:
    0 1px 2px rgba(20, 30, 55, .07),
    0 5px 12px -4px rgba(20, 30, 55, .13);
  --clay-shadow-2:
    0 2px 5px rgba(20, 30, 55, .08),
    0 18px 34px -14px rgba(20, 30, 55, .22);
  --clay-shadow-3:
    0 5px 12px rgba(20, 30, 55, .12),
    0 40px 72px -30px rgba(20, 30, 55, .34);

  /* Light clay carries the volume mostly in the rims: the surfaces are close in
     value, so a hard white line would be the only thing visible. Blurred. */
  --clay-lit:
    inset 0 2px 1px -1px rgba(255, 255, 255, 1),
    inset 0 2px 4px -2px rgba(255, 255, 255, .9);
  --clay-shade: inset 0 -3px 5px -3px rgba(20, 30, 55, .16);
  --clay-press:
    inset 0 2px 6px rgba(20, 30, 55, .14),
    inset 0 -1px 0 rgba(255, 255, 255, .8);
  --clay-ring: 0 0 0 3px rgba(43, 98, 217, .24);

  --clay-sheen: linear-gradient(180deg, rgba(255, 255, 255, .75), rgba(255, 255, 255, 0) 58%);
  --clay-sheen-slab: linear-gradient(180deg, rgba(255, 255, 255, .6), rgba(255, 255, 255, 0) 130px);
  --clay-glow: radial-gradient(1100px 520px at 18% -12%, rgba(80, 130, 235, .09), transparent 62%);

  --theme-popup-shadow: var(--clay-shadow-3), var(--clay-lit);
}

/* -----------------------------------------------------------------------------
 * 3b. Accent
 *
 * Stock Huly runs on #205DC2 -- a mid-value, mid-saturation navy that reads as
 * dated, and not only because of the hue: a flat fill of it under a neutral
 * grey shadow is the exact visual language soft 3D replaced. Both halves are
 * fixed here. The hue moves to a softer indigo, and primary buttons get a
 * shadow tinted with their own colour further down (section 7) -- a coloured
 * object casting a grey shadow is the single most dating detail on a button.
 *
 * This is the one place the accent is defined. Every accent-bearing token in
 * the platform is mapped onto these four values, so changing the scheme means
 * editing this block and nothing else.
 *
 * Contrast is checked against white button labels: #4F57D9 gives 5.5:1 and
 * #5A63E0 gives 4.9:1, both clear of the 4.5:1 floor for 13px text.
 * -------------------------------------------------------------------------- */

html.theme-dark {
  --clay-accent: #5A63E0;
  /* Hover goes *darker*, not lighter, in both themes. Lightening the fill on a
     dark ground is the intuitive move, but #6C74EA drops the white label to
     3.94:1 -- under the 4.5:1 floor. The lift is carried by the sheen and the
     growing coloured shadow instead, which is where soft 3D wants it anyway. */
  --clay-accent-hover: #4F57D9;
  --clay-accent-press: #4249C4;
  --clay-accent-text: #9AA2F5;                      /* accent on a dark ground */
  --clay-accent-shadow: rgba(58, 66, 190, .55);

  --clay-ring: 0 0 0 3px rgba(108, 116, 234, .34);
  --clay-glow: radial-gradient(1100px 520px at 18% -12%, rgba(122, 132, 255, .07), transparent 62%);
  --theme-link-color: var(--clay-accent-text);
  --theme-editbox-focus-border: var(--clay-accent-hover);
  --theme-toggle-on-bg-color: var(--clay-accent);
  --theme-toggle-on-bg-hover: var(--clay-accent-hover);
  --global-accent-BackgroundColor: var(--clay-accent);
  --global-accent-TextColor: var(--clay-accent-text);
  --global-primary-LinkColor: var(--clay-accent-text);
  --global-focus-BorderColor: var(--clay-accent);
  --theme-tablist-plain-color: var(--clay-accent);
}

html.theme-light {
  --clay-accent: #4F57D9;
  --clay-accent-hover: #454DCC;
  --clay-accent-press: #3C43BC;
  --clay-accent-text: #4A52D4;                      /* accent on a light ground */
  --clay-accent-shadow: rgba(79, 87, 217, .38);

  --clay-ring: 0 0 0 3px rgba(79, 87, 217, .26);
  --clay-glow: radial-gradient(1100px 520px at 18% -12%, rgba(90, 99, 224, .09), transparent 62%);
  --theme-link-color: var(--clay-accent-text);
  --theme-editbox-focus-border: var(--clay-accent);
  --theme-toggle-on-bg-color: var(--clay-accent);
  --theme-toggle-on-bg-hover: var(--clay-accent-hover);
  --theme-popup-checkicon: var(--clay-accent);
  --global-accent-BackgroundColor: var(--clay-accent);
  --global-accent-TextColor: var(--clay-accent-text);
  --global-primary-LinkColor: var(--clay-accent-text);
  --global-focus-BorderColor: var(--clay-accent);
  --theme-tablist-plain-color: var(--clay-accent);
}

/* The button palettes live on the universal selector in stock Huly, same as the
   radius scale, so they have to be forced the same way. */
* {
  --primary-button-default: var(--clay-accent) !important;
  --primary-button-hovered: var(--clay-accent-hover) !important;
  --primary-button-pressed: var(--clay-accent-press) !important;
  --primary-button-focused: var(--clay-accent) !important;
  --primary-button-outline: var(--clay-accent-hover) !important;
  --button-primary-BackgroundColor: var(--clay-accent) !important;
  --button-primary-hover-BackgroundColor: var(--clay-accent-hover) !important;
  --button-primary-active-BackgroundColor: var(--clay-accent-press) !important;
  --button-primary-loading-LabelColor: var(--clay-accent-text) !important;
  --selector-active-BackgroundColor: var(--clay-accent) !important;
}

/* -----------------------------------------------------------------------------
 * 3c. "Soft" variant  (opt-in: add class `clay-soft` to <html>)
 *
 * A quieter reading of the same idea. Everything above stays the definition of
 * the default; this block only re-tunes it, and nothing here is loaded unless
 * the class is present, so the two can be compared side by side.
 *
 * What actually makes it softer, in order of how much it does:
 *
 *   1. The neutrals stop being neutral. Greys carry a low-chroma violet cast,
 *      and neither end of the range goes to an extreme -- the light canvas is
 *      an off-white with a lilac bias, the dark canvas is a charcoal lifted
 *      well off black. Pure #000/#FFF is what makes an interface feel hard.
 *   2. Text contrast comes down from maximum to comfortable. Captions are not
 *      pure black or pure white any more, and body text sits around 8:1
 *      instead of 16:1 -- still far above the 4.5:1 floor.
 *   3. Shadows widen and lose roughly half their opacity, and the bottom rim
 *      nearly disappears. The volume is still there, it is just further away.
 *   4. Radii go up one more step, to 22px on slabs.
 *
 * The accent is desaturated to a dusty periwinkle. The hue family is kept on
 * purpose: violet is the one part of the wheel that does not collide with the
 * semantic colours a tracker already spends (red urgent, orange warning, green
 * done), which is why sage or rose would be the wrong kind of gentle here.
 * -------------------------------------------------------------------------- */

html.clay-soft {
  --clay-r-xs: .5rem;     /*  8px */
  --clay-r-sm: .75rem;    /* 12px */
  --clay-r-md: .875rem;   /* 14px */
  --clay-r-lg: 1.125rem;  /* 18px */
  --clay-r-xl: 1.375rem;  /* 22px */
  --clay-gap: .75rem;
}

html.clay-soft * {
  --min-BorderRadius: .3125rem !important;
  --extra-small-BorderRadius: .5rem !important;
  --extra-small-focus-BorderRadius: .625rem !important;
  --small-BorderRadius: .75rem !important;
  --small-focus-BorderRadius: .875rem !important;
  --medium-BorderRadius: .875rem !important;
  --medium-focus-BorderRadius: 1rem !important;
  --large-BorderRadius: 1.375rem !important;
  --large-focus-BorderRadius: 1.5rem !important;

  --global-popover-ShadowBlur: 2.5rem !important;
  --global-popover-ShadowY: 1rem !important;
  --global-modal-ShadowBlur: 4rem !important;
  --global-modal-ShadowY: 2.25rem !important;

  --primary-button-default: #6366C9 !important;
  --primary-button-hovered: #5A5EBE !important;
  --primary-button-pressed: #4F5299 !important;
  --primary-button-focused: #6366C9 !important;
  --primary-button-outline: #5A5EBE !important;
  --button-primary-BackgroundColor: #6366C9 !important;
  --button-primary-hover-BackgroundColor: #5A5EBE !important;
  --button-primary-active-BackgroundColor: #4F5299 !important;
  --selector-active-BackgroundColor: #6366C9 !important;
}

html.clay-soft.theme-light {
  --theme-back-color: #EEEDF5;
  --theme-bg-color: #F3F2F9;
  --theme-statusbar-color: #EEEDF5;
  --theme-navpanel-color: #F7F6FC;
  --theme-panel-color: #FCFBFE;
  --theme-comp-header-color: #FDFDFF;
  --theme-bg-divider-color: #E6E4F0;
  --theme-overlay-color: rgba(40, 34, 70, .18);

  --theme-popup-color: #FFFFFF;
  --theme-popup-trans-color: #FFFFFFee;
  --theme-popup-header: #F5F4FB;
  --theme-popup-hover: #F1EFF9;
  --theme-popup-divider: rgba(45, 38, 85, .07);
  --theme-popup-deactivated: #E3E1EE;

  --theme-list-row-color: #FCFBFE;
  --theme-list-subheader-color: #F5F4FB;
  --theme-list-button-color: #F3F2F9;
  --theme-list-button-hover: #EBE9F5;
  --theme-link-button-color: #F1EFF9;
  --theme-link-button-hover: #E8E6F3;
  --theme-table-header-color: #F5F4FB;
  --theme-table-row-color: #FCFBFE;
  --theme-button-container-color: #EFEDF7;

  --theme-divider-color: rgba(45, 38, 85, .065);
  --theme-navpanel-divider: rgba(45, 38, 85, .07);
  --theme-navpanel-border: rgba(45, 38, 85, .05);
  --theme-list-divider-color: rgba(45, 38, 85, .06);
  --theme-list-border-color: rgba(45, 38, 85, .05);
  --theme-table-border-color: rgba(45, 38, 85, .07);
  --theme-button-border: rgba(45, 38, 85, .08);
  --theme-refinput-border: rgba(45, 38, 85, .08);
  --theme-refinput-divider: rgba(45, 38, 85, .06);

  --theme-navpanel-hovered: rgba(99, 102, 201, .06);
  --theme-navpanel-selected: rgba(99, 102, 201, .12);
  --theme-button-default: rgba(255, 255, 255, .8);
  --theme-button-hovered: rgba(99, 102, 201, .07);
  --theme-button-pressed: rgba(99, 102, 201, .13);
  --theme-button-focused: rgba(99, 102, 201, .09);

  --theme-kanban-card-bg-color: #FFFFFF;
  --theme-kanban-card-border: rgba(45, 38, 85, .05);
  --theme-kanban-card-footer: rgba(45, 38, 85, .035);

  /* 8.5:1 for body, 5.3:1 for the muted tier -- comfortable, not maximal. */
  --theme-caption-color: #1D1B2E;
  --theme-content-color: rgba(29, 27, 46, .80);
  --theme-dark-color: rgba(29, 27, 46, .58);
  --theme-halfcontent-color: rgba(29, 27, 46, .48);
  --theme-darker-color: rgba(29, 27, 46, .40);
  --theme-tooltip-bg: #32304A;

  --global-surface-01-BackgroundColor: #F7F6FC;
  --global-surface-01-hover-BackgroundColor: #F1EFF9;
  --global-surface-02-BackgroundColor: #FCFBFE;
  --global-surface-01-BorderColor: rgba(45, 38, 85, .07);
  --global-surface-02-BorderColor: rgba(45, 38, 85, .06);
  --global-ui-BorderColor: rgba(45, 38, 85, .08);
  --global-popover-ShadowColor: rgba(45, 38, 85, .14);
  --global-modal-ShadowColor: rgba(45, 38, 85, .20);

  --clay-accent: #6366C9;
  --clay-accent-hover: #5A5EBE;
  --clay-accent-press: #4F5299;
  --clay-accent-text: #5A5EC0;
  --clay-accent-shadow: rgba(99, 102, 201, .26);
  --clay-ring: 0 0 0 3px rgba(99, 102, 201, .22);

  --clay-shadow-1:
    0 1px 2px rgba(45, 38, 85, .04),
    0 4px 14px -5px rgba(45, 38, 85, .08);
  --clay-shadow-2:
    0 2px 4px rgba(45, 38, 85, .05),
    0 18px 40px -16px rgba(45, 38, 85, .14);
  --clay-shadow-3:
    0 4px 12px rgba(45, 38, 85, .07),
    0 44px 84px -34px rgba(45, 38, 85, .22);

  --clay-lit:
    inset 0 2px 1px -1px rgba(255, 255, 255, .95),
    inset 0 2px 5px -2px rgba(255, 255, 255, .85);
  --clay-shade: inset 0 -3px 6px -4px rgba(45, 38, 85, .09);
  --clay-press:
    inset 0 2px 6px rgba(45, 38, 85, .08),
    inset 0 -1px 0 rgba(255, 255, 255, .7);

  --clay-sheen: linear-gradient(180deg, rgba(255, 255, 255, .6), rgba(255, 255, 255, 0) 62%);
  --clay-sheen-slab: linear-gradient(180deg, rgba(255, 255, 255, .5), rgba(255, 255, 255, 0) 150px);
  --clay-glow: radial-gradient(1200px 560px at 20% -14%, rgba(120, 120, 220, .10), transparent 64%);

  --theme-link-color: var(--clay-accent-text);
  --theme-editbox-focus-border: var(--clay-accent);
  --theme-toggle-on-bg-color: var(--clay-accent);
  --theme-toggle-on-bg-hover: var(--clay-accent-hover);
  --theme-popup-checkicon: var(--clay-accent);
  --global-accent-BackgroundColor: var(--clay-accent);
  --global-accent-TextColor: var(--clay-accent-text);
  --global-primary-LinkColor: var(--clay-accent-text);
  --global-focus-BorderColor: var(--clay-accent);
  --theme-tablist-plain-color: var(--clay-accent);
  --theme-popup-shadow: var(--clay-shadow-3), var(--clay-lit);
}

html.clay-soft.theme-dark {
  --theme-back-color: #141320;
  --theme-bg-color: #181726;
  --theme-statusbar-color: #141320;
  --theme-navpanel-color: #1A1928;
  --theme-panel-color: #1E1D2E;
  --theme-comp-header-color: #232236;
  --theme-bg-divider-color: #282740;
  --theme-overlay-color: rgba(10, 8, 20, .5);

  --theme-popup-color: #262538;
  --theme-popup-trans-color: #262538ee;
  --theme-popup-header: #2E2D44;
  --theme-popup-hover: #33324B;
  --theme-popup-divider: rgba(173, 176, 240, .10);
  --theme-popup-deactivated: #1E1D2E;

  --theme-list-row-color: #232232;
  --theme-list-subheader-color: #1F1E2E;
  --theme-list-button-color: #2A2940;
  --theme-list-button-hover: #322F4A;
  --theme-link-button-color: #2A2940;
  --theme-link-button-hover: #322F4A;
  --theme-table-header-color: #1F1E2E;
  --theme-table-row-color: #232232;
  --theme-button-container-color: #262538;

  --theme-divider-color: rgba(173, 176, 240, .08);
  --theme-navpanel-divider: rgba(173, 176, 240, .09);
  --theme-navpanel-border: rgba(173, 176, 240, .07);
  --theme-list-divider-color: rgba(173, 176, 240, .07);
  --theme-list-border-color: rgba(173, 176, 240, .05);
  --theme-table-border-color: rgba(173, 176, 240, .08);
  --theme-button-border: rgba(173, 176, 240, .10);
  --theme-refinput-border: rgba(173, 176, 240, .10);
  --theme-refinput-divider: rgba(173, 176, 240, .07);

  --theme-navpanel-hovered: rgba(173, 176, 240, .06);
  --theme-navpanel-selected: rgba(173, 176, 240, .12);
  --theme-button-default: rgba(173, 176, 240, .05);
  --theme-button-hovered: rgba(173, 176, 240, .09);
  --theme-button-pressed: rgba(173, 176, 240, .14);
  --theme-button-focused: rgba(173, 176, 240, .09);

  --theme-kanban-card-bg-color: #262538;
  --theme-kanban-card-border: rgba(173, 176, 240, .07);
  --theme-kanban-card-footer: rgba(173, 176, 240, .05);

  --theme-caption-color: #F0EEF8;
  --theme-content-color: rgba(240, 238, 248, .80);
  --theme-dark-color: rgba(240, 238, 248, .60);
  --theme-halfcontent-color: rgba(240, 238, 248, .48);
  --theme-darker-color: rgba(240, 238, 248, .40);
  --theme-tooltip-bg: #2E2D44;

  --global-surface-01-BackgroundColor: #1A1928;
  --global-surface-01-hover-BackgroundColor: #1F1E2E;
  --global-surface-02-BackgroundColor: #1E1D2E;
  --global-surface-01-BorderColor: rgba(173, 176, 240, .08);
  --global-surface-02-BorderColor: rgba(173, 176, 240, .08);
  --global-popover-BackgroundColor: #262538;
  --global-popover-hover-BackgroundColor: #33324B;
  --global-popover-BorderColor: rgba(173, 176, 240, .10);
  --global-ui-BorderColor: rgba(173, 176, 240, .10);
  --global-ui-hover-BackgroundColor: rgba(173, 176, 240, .10);
  --global-ui-active-BackgroundColor: rgba(173, 176, 240, .16);
  --global-popover-ShadowColor: rgba(8, 6, 18, .5);
  --global-modal-ShadowColor: rgba(8, 6, 18, .58);

  --clay-accent: #6366C9;
  --clay-accent-hover: #5A5EBE;
  --clay-accent-press: #4F5299;
  --clay-accent-text: #ADB0F0;
  --clay-accent-shadow: rgba(56, 58, 140, .48);
  --clay-ring: 0 0 0 3px rgba(120, 124, 214, .30);

  --clay-shadow-1:
    0 1px 2px rgba(8, 6, 18, .30),
    0 6px 16px -6px rgba(8, 6, 18, .36);
  --clay-shadow-2:
    0 2px 5px rgba(8, 6, 18, .32),
    0 20px 40px -16px rgba(8, 6, 18, .46);
  --clay-shadow-3:
    0 5px 14px rgba(8, 6, 18, .34),
    0 46px 84px -34px rgba(8, 6, 18, .60);

  --clay-lit:
    inset 0 2px 1px -1px rgba(255, 255, 255, .07),
    inset 0 1px 4px -1px rgba(255, 255, 255, .045);
  --clay-shade: inset 0 -3px 6px -4px rgba(0, 0, 0, .40);
  --clay-press:
    inset 0 2px 6px rgba(0, 0, 0, .35),
    inset 0 -1px 0 rgba(255, 255, 255, .03);

  --clay-sheen: linear-gradient(180deg, rgba(255, 255, 255, .045), rgba(255, 255, 255, 0) 62%);
  --clay-sheen-slab: linear-gradient(180deg, rgba(255, 255, 255, .04), rgba(255, 255, 255, 0) 150px);
  --clay-glow: radial-gradient(1200px 560px at 20% -14%, rgba(140, 143, 255, .09), transparent 64%);

  --theme-link-color: var(--clay-accent-text);
  --theme-editbox-focus-border: var(--clay-accent-hover);
  --theme-toggle-on-bg-color: var(--clay-accent);
  --theme-toggle-on-bg-hover: var(--clay-accent-hover);
  --global-accent-BackgroundColor: var(--clay-accent);
  --global-accent-TextColor: var(--clay-accent-text);
  --global-primary-LinkColor: var(--clay-accent-text);
  --global-focus-BorderColor: var(--clay-accent);
  --theme-tablist-plain-color: var(--clay-accent);
  --theme-popup-shadow: var(--clay-shadow-3), var(--clay-lit);
}

/* -----------------------------------------------------------------------------
 * Spring palette (client-supplied), and how it is spent
 *
 * Sixteen pastels. Two facts decide everything about how they get used:
 *
 *   - Not one of them carries white text. The best is Watermelon at 2.54:1
 *     against a 4.5:1 floor. Every one of them carries dark text easily
 *     (6.5:1 to 14.5:1). So pastel fills take an ink label, never a white one.
 *     That is not a preference, it is the arithmetic of light colours.
 *   - As a 16px dot on a white panel, most of them disappear -- Ivory is
 *     1.14:1, Mint 1.50:1. So markers use the same hues one step deeper
 *     (--spring-*-mark), while the pastels themselves go where there is enough
 *     area to read: button fills, chips, tints.
 *
 * Text, dividers and surfaces stay neutral. A palette this soft can colour an
 * interface without having to carry it.
 * -------------------------------------------------------------------------- */

html.clay-nord {
  --spring-ivory: #FAF0D2;
  --spring-peach: #FBDCB4;
  --spring-buttercup: #F8E07E;
  --spring-coral: #EF9084;
  --spring-blossom: #F6C6D5;
  --spring-watermelon: #EE8296;
  --spring-lilac: #CDBEEB;
  --spring-periwinkle: #A9BDEE;
  --spring-seaspray: #BEE0E4;
  --spring-mint: #B5DCC0;
  --spring-fresh-green: #B7DE85;
  --spring-limeade: #CDDD84;
  --spring-sunshine: #F7DA70;
  --spring-tangerine: #F0A860;
  --spring-sky: #A6C8EA;
  --spring-turquoise: #7FCFD0;

  /* same hues, one step deeper -- for dots and small icons */
  --spring-coral-mark: #E2705F;
  --spring-watermelon-mark: #E06B82;
  --spring-tangerine-mark: #D98F45;
  --spring-periwinkle-mark: #7F93D6;
  --spring-mint-mark: #6FBF95;
  --spring-sky-mark: #7FAEDC;
  --spring-turquoise-mark: #4FB6B8;
}

/* -----------------------------------------------------------------------------
 * 3d. "Nord" variant  (opt-in: add class `clay-nord` to <html>)
 *
 * The company blue, used the way current interfaces use brand colour rather
 * than the way 2005 enterprise software did.
 *
 * The first attempt at this variant tinted the furniture: a pale sky-blue
 * navigator beside a white content pane. That is Windows Explorer, and no
 * change of hue fixes it, because the dated part is not the blue -- it is
 * painting the chrome with it. Two rules come out of that:
 *
 *   1. Surfaces stay neutral. The canvas is a cool grey whose red-to-blue
 *      spread is 6 points; the old tint was 42. It reads as grey, not as a
 *      blue wash, and that single change removes most of the period feel.
 *   2. Blue appears only where it means something -- the primary button, the
 *      active nav item, links, focus, selection. Brand colour as signal, not
 *      as wallpaper.
 *
 * The hue also moves off the mid-value royal blue (#1E60B4) that Luna and
 * Office 2003 made generic, toward a brighter, cleaner azure. That is the end
 * of the range the certificate's own gradient runs to, so it is no less "the
 * company blue" -- it is the modern half of it.
 *
 * The primary button carries a two-stop gradient echoing that graphic. Both
 * stops clear 4.5:1 against the white label, so no part of the text lands on
 * a fill that is too light.
 * -------------------------------------------------------------------------- */

html.clay-nord {
  --clay-r-xs: .5rem;
  --clay-r-sm: .75rem;
  --clay-r-md: .875rem;
  --clay-r-lg: 1.125rem;
  --clay-r-xl: 1.375rem;
  --clay-gap: .75rem;
}

html.clay-nord * {
  --min-BorderRadius: .3125rem !important;
  --extra-small-BorderRadius: .5rem !important;
  --extra-small-focus-BorderRadius: .625rem !important;
  --small-BorderRadius: .75rem !important;
  --small-focus-BorderRadius: .875rem !important;
  --medium-BorderRadius: .875rem !important;
  --medium-focus-BorderRadius: 1rem !important;
  --large-BorderRadius: 1.375rem !important;
  --large-focus-BorderRadius: 1.5rem !important;

  --global-popover-ShadowBlur: 2.5rem !important;
  --global-popover-ShadowY: 1rem !important;
  --global-modal-ShadowBlur: 4rem !important;
  --global-modal-ShadowY: 2.25rem !important;

  /* The primary button is the light blue off the certificate, not the deep
     one, with a white label -- chosen deliberately for the look. Worth knowing:
     white on #6FB6EC measures 2.2:1 against a 4.5:1 readability floor, so the
     label washes out on a dim or glare-hit screen. Two ways back if that ever
     bites: a navy label (#0F2A47, 6.6:1) keeps this exact blue, or deepening
     the fill to about #1F7BBE lets white clear the bar. Deep blue stays on
     links, toggles and focus, where a pale fill would read as disabled. */
  --primary-button-default: #A6C8EA !important;
  --primary-button-hovered: #93BBE4 !important;
  --primary-button-pressed: #80AEDD !important;
  --primary-button-focused: #A6C8EA !important;
  --primary-button-outline: #93BBE4 !important;
  --primary-button-color: #12202F !important;
  --primary-button-content-color: rgba(18, 32, 47, .78) !important;
  --button-primary-BackgroundColor: #A6C8EA !important;
  --button-primary-hover-BackgroundColor: #93BBE4 !important;
  --button-primary-active-BackgroundColor: #80AEDD !important;
  --button-primary-BorderColor: transparent !important;
  --selector-active-BackgroundColor: #17509E !important;
}

/* Both button families read the label from a different token, so paint it
   directly -- the plus icon follows through currentColor. */
html.clay-nord .antiButton.primary,
html.clay-nord .hulyButton.primary {
  color: #12202F !important;
}

html.clay-nord.theme-light {
  /* Cool grey, not blue. R-to-B spread of 6 points is the whole point. */
  --theme-back-color: #F1F0EC;
  --theme-bg-color: #F2F4F7;
  --theme-statusbar-color: #F1F0EC;
  --theme-navpanel-color: #FAFBFD;
  --theme-panel-color: #FFFFFF;
  --theme-comp-header-color: #FFFFFF;
  --theme-bg-divider-color: #E6E9EE;
  --theme-overlay-color: rgba(15, 27, 45, .20);

  --theme-popup-color: #FFFFFF;
  --theme-popup-trans-color: #FFFFFFee;
  --theme-popup-header: #F5F6F9;
  --theme-popup-hover: #F0F2F6;
  --theme-popup-divider: rgba(15, 27, 45, .08);
  --theme-popup-deactivated: #E1E4EA;

  --theme-list-row-color: #FFFFFF;
  --theme-list-subheader-color: #F5F6F9;
  --theme-list-button-color: #F0F2F6;
  --theme-list-button-hover: #E7EAF0;
  --theme-link-button-color: #F0F2F6;
  --theme-link-button-hover: #E7EAF0;
  --theme-table-header-color: #F5F6F9;
  --theme-table-row-color: #FFFFFF;
  --theme-button-container-color: #EEF0F4;

  --theme-divider-color: rgba(15, 27, 45, .075);
  --theme-navpanel-divider: rgba(15, 27, 45, .08);
  --theme-navpanel-border: rgba(15, 27, 45, .06);
  --theme-list-divider-color: rgba(15, 27, 45, .07);
  --theme-list-border-color: rgba(15, 27, 45, .06);
  --theme-table-border-color: rgba(15, 27, 45, .08);
  --theme-button-border: rgba(15, 27, 45, .09);
  --theme-refinput-border: rgba(15, 27, 45, .09);
  --theme-refinput-divider: rgba(15, 27, 45, .07);

  /* The one place the blue touches the furniture: the item you are on. */
  --theme-navpanel-hovered: rgba(15, 27, 45, .045);
  --theme-navpanel-selected: rgba(166, 200, 234, .55);
  --theme-button-default: rgba(255, 255, 255, .85);
  --theme-button-hovered: rgba(15, 27, 45, .05);
  --theme-button-pressed: rgba(15, 27, 45, .09);
  --theme-button-focused: rgba(166, 200, 234, .45);

  --theme-kanban-card-bg-color: #FFFFFF;
  --theme-kanban-card-border: rgba(15, 27, 45, .06);
  --theme-kanban-card-footer: rgba(15, 27, 45, .04);

  /* 9.1:1 body, 5.6:1 secondary. */
  --theme-caption-color: #0F1B2D;
  --theme-content-color: rgba(15, 27, 45, .80);
  --theme-dark-color: rgba(15, 27, 45, .66);
  --theme-halfcontent-color: rgba(15, 27, 45, .58);
  --theme-darker-color: rgba(15, 27, 45, .50);
  --theme-tooltip-bg: #1B2534;

  /* The hulyXxx text ramp, same reasoning as the dark block. Here it was not
     merely unmeasured but actually short: stock tertiary #7B879E lands at
     3.62:1 on this palette's white panel, under the 4.5:1 floor -- and that
     token paints the project names in the navigator, which is a list people
     read every few minutes. Measured against --theme-panel-color #FFFFFF:

       primary 17.3:1  secondary 9.0:1  tertiary 5.6:1  disabled 3.5:1

     Disabled stays under 4.5:1 on purpose: it marks unavailable controls,
     which 1.4.3 exempts, and lifting it would make "off" read as "on". */
  --global-primary-TextColor: #0F1B2D;
  --global-secondary-TextColor: #3C4A60;
  --global-tertiary-TextColor: #5A687F;
  --global-disabled-TextColor: #7E8A9D;

  /* Pastel semantics. These are markers -- a priority dot only has to be
     identifiable, not legible, so desaturating them costs nothing and takes a
     lot of noise out of a long list. --theme-error-color is the exception: it
     paints error *text*, so it keeps enough weight to clear 4.5:1. */
  --global-urgent-PriorityColor: var(--spring-coral-mark);
  --global-high-PriorityColor: var(--spring-coral-mark);
  --global-medium-PriorityColor: var(--spring-tangerine-mark);
  --global-low-PriorityColor: var(--spring-periwinkle-mark);
  --global-no-priority-PriorityColor: #B4BCC8;
  --global-disabled-PriorityColor: #C6CCD5;
  --theme-urgent-color: var(--spring-coral-mark);
  --theme-warning-color: var(--spring-tangerine-mark);
  --theme-won-color: var(--spring-mint-mark);
  --theme-lost-color: var(--spring-watermelon-mark);
  /* Error paints text, so it is the one semantic that cannot be pastel. */
  --theme-error-color: #B8564A;

  --global-surface-01-BackgroundColor: #FAFBFD;
  --global-surface-01-hover-BackgroundColor: #F0F2F6;
  --global-surface-02-BackgroundColor: #FFFFFF;
  --global-surface-01-BorderColor: rgba(15, 27, 45, .08);
  --global-surface-02-BorderColor: rgba(15, 27, 45, .07);
  --global-ui-BorderColor: rgba(15, 27, 45, .09);
  --global-popover-ShadowColor: rgba(15, 27, 45, .14);
  --global-modal-ShadowColor: rgba(15, 27, 45, .20);

  --clay-accent: #17509E;
  --clay-accent-hover: #134489;
  --clay-accent-press: #103A75;
  --clay-accent-text: #17509E;
  --clay-accent-shadow: rgba(23, 80, 158, .26);
  --clay-ring: 0 0 0 3px rgba(23, 80, 158, .26);

  --clay-shadow-1:
    0 1px 2px rgba(15, 27, 45, .05),
    0 4px 14px -5px rgba(15, 27, 45, .09);
  --clay-shadow-2:
    0 2px 4px rgba(15, 27, 45, .06),
    0 18px 40px -16px rgba(15, 27, 45, .15);
  --clay-shadow-3:
    0 4px 12px rgba(15, 27, 45, .08),
    0 44px 84px -34px rgba(15, 27, 45, .24);

  --clay-lit:
    inset 0 2px 1px -1px rgba(255, 255, 255, .95),
    inset 0 2px 5px -2px rgba(255, 255, 255, .85);
  --clay-shade: inset 0 -3px 6px -4px rgba(15, 27, 45, .10);
  --clay-press:
    inset 0 2px 6px rgba(15, 27, 45, .09),
    inset 0 -1px 0 rgba(255, 255, 255, .7);

  --clay-sheen: linear-gradient(180deg, rgba(255, 255, 255, .65), rgba(255, 255, 255, 0) 62%);
  --clay-sheen-slab: linear-gradient(180deg, rgba(255, 255, 255, .55), rgba(255, 255, 255, 0) 150px);
  /* Barely there -- enough to keep the canvas from reading as flat grey. */
  --clay-glow: radial-gradient(1200px 560px at 20% -14%, rgba(166, 200, 234, .22), transparent 64%);

  --theme-link-color: var(--clay-accent-text);
  --theme-editbox-focus-border: var(--clay-accent);
  --theme-toggle-on-bg-color: var(--clay-accent);
  --theme-toggle-on-bg-hover: var(--clay-accent-hover);
  --theme-popup-checkicon: var(--clay-accent);
  --global-accent-BackgroundColor: var(--clay-accent);
  --global-accent-TextColor: var(--clay-accent-text);
  --global-primary-LinkColor: var(--clay-accent-text);
  --global-focus-BorderColor: var(--clay-accent);
  --theme-tablist-plain-color: var(--clay-accent);
  --theme-popup-shadow: var(--clay-shadow-3), var(--clay-lit);
}

html.clay-nord.theme-dark {
  --theme-back-color: #0B111C;
  --theme-bg-color: #0F1622;
  --theme-statusbar-color: #0B111C;
  --theme-navpanel-color: #121A28;
  --theme-panel-color: #141D2C;
  --theme-comp-header-color: #1B2534;
  --theme-bg-divider-color: #202B3C;
  --theme-overlay-color: rgba(5, 9, 16, .55);

  --theme-popup-color: #1B2534;
  --theme-popup-trans-color: #1B2534ee;
  --theme-popup-header: #232F41;
  --theme-popup-hover: #28364B;
  --theme-popup-divider: rgba(200, 214, 233, .11);
  --theme-popup-deactivated: #141D2C;

  --theme-list-row-color: #182234;
  --theme-list-subheader-color: #151F2E;
  --theme-list-button-color: #232F41;
  --theme-list-button-hover: #2A374C;
  --theme-link-button-color: #232F41;
  --theme-link-button-hover: #2A374C;
  --theme-table-header-color: #151F2E;
  --theme-table-row-color: #182234;
  --theme-button-container-color: #1B2534;

  --theme-divider-color: rgba(200, 214, 233, .09);
  --theme-navpanel-divider: rgba(200, 214, 233, .10);
  --theme-navpanel-border: rgba(200, 214, 233, .08);
  --theme-list-divider-color: rgba(200, 214, 233, .08);
  --theme-list-border-color: rgba(200, 214, 233, .06);
  --theme-table-border-color: rgba(200, 214, 233, .09);
  --theme-button-border: rgba(200, 214, 233, .11);
  --theme-refinput-border: rgba(200, 214, 233, .11);
  --theme-refinput-divider: rgba(200, 214, 233, .08);

  --theme-navpanel-hovered: rgba(200, 214, 233, .06);
  --theme-navpanel-selected: rgba(166, 200, 234, .22);
  --theme-button-default: rgba(200, 214, 233, .06);
  --theme-button-hovered: rgba(200, 214, 233, .10);
  --theme-button-pressed: rgba(200, 214, 233, .15);
  --theme-button-focused: rgba(166, 200, 234, .18);

  --theme-kanban-card-bg-color: #1B2534;
  --theme-kanban-card-border: rgba(200, 214, 233, .08);
  --theme-kanban-card-footer: rgba(200, 214, 233, .06);

  --theme-caption-color: #EDF1F7;
  --theme-content-color: rgba(237, 241, 247, .84);
  --theme-dark-color: rgba(237, 241, 247, .64);
  --theme-halfcontent-color: rgba(237, 241, 247, .55);
  --theme-darker-color: rgba(237, 241, 247, .46);
  --theme-tooltip-bg: #232F41;

  /* The other text ramp. Huly runs two in parallel: the legacy --theme-*
     colours tuned just above, used by antiXxx components, and
     --global-*-TextColor, used by every hulyXxx one -- navigator labels,
     headers, breadcrumbs, chips. Only the first was ever part of this
     palette; the second kept stock values, which happened to sit on Nord
     surfaces without anyone checking. Measured, they were fine here
     (tertiary #8E99AF is 5.9:1 on the panel), but "fine by luck" stops being
     true the first time a surface moves. Pinned to this palette's own ramp,
     measured against --theme-panel-color #141D2C:

       primary 14.9:1  secondary 10.4:1  tertiary 7.0:1  disabled 4.5:1

     Stock declares these on `.theme-dark`, so `html.clay-nord.theme-dark`
     wins on specificity and no !important is needed. */
  --global-primary-TextColor: #EDF1F7;
  --global-secondary-TextColor: #C3CCDA;
  --global-tertiary-TextColor: #9BA7BB;
  --global-disabled-TextColor: #78849A;

  --global-urgent-PriorityColor: var(--spring-coral);
  --global-high-PriorityColor: var(--spring-coral);
  --global-medium-PriorityColor: var(--spring-tangerine);
  --global-low-PriorityColor: var(--spring-periwinkle);
  --global-no-priority-PriorityColor: #8A94A6;
  --global-disabled-PriorityColor: #6B7686;
  --theme-urgent-color: var(--spring-coral);
  --theme-warning-color: var(--spring-tangerine);
  --theme-won-color: var(--spring-mint);
  --theme-lost-color: var(--spring-watermelon);
  --theme-error-color: var(--spring-watermelon);

  --global-surface-01-BackgroundColor: #121A28;
  --global-surface-01-hover-BackgroundColor: #151F2E;
  --global-surface-02-BackgroundColor: #141D2C;
  --global-surface-01-BorderColor: rgba(200, 214, 233, .09);
  --global-surface-02-BorderColor: rgba(200, 214, 233, .09);
  --global-popover-BackgroundColor: #1B2534;
  --global-popover-hover-BackgroundColor: #28364B;
  --global-popover-BorderColor: rgba(200, 214, 233, .12);
  --global-ui-BorderColor: rgba(200, 214, 233, .11);
  --global-ui-hover-BackgroundColor: rgba(200, 214, 233, .10);
  --global-ui-active-BackgroundColor: rgba(200, 214, 233, .17);
  --global-popover-ShadowColor: rgba(3, 7, 14, .55);
  --global-modal-ShadowColor: rgba(3, 7, 14, .62);

  --clay-accent: #2060BC;
  --clay-accent-hover: #1A55A8;
  --clay-accent-press: #154892;
  --clay-accent-text: #7FB2FF;
  --clay-accent-shadow: rgba(12, 44, 96, .55);
  --clay-ring: 0 0 0 3px rgba(32, 96, 188, .38);

  --clay-shadow-1:
    0 1px 2px rgba(3, 7, 14, .32),
    0 6px 16px -6px rgba(3, 7, 14, .38);
  --clay-shadow-2:
    0 2px 5px rgba(3, 7, 14, .34),
    0 20px 40px -16px rgba(3, 7, 14, .48);
  --clay-shadow-3:
    0 5px 14px rgba(3, 7, 14, .36),
    0 46px 84px -34px rgba(3, 7, 14, .62);

  --clay-lit:
    inset 0 2px 1px -1px rgba(255, 255, 255, .075),
    inset 0 1px 4px -1px rgba(255, 255, 255, .05);
  --clay-shade: inset 0 -3px 6px -4px rgba(0, 0, 0, .42);
  --clay-press:
    inset 0 2px 6px rgba(0, 0, 0, .38),
    inset 0 -1px 0 rgba(255, 255, 255, .035);

  --clay-sheen: linear-gradient(180deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, 0) 62%);
  --clay-sheen-slab: linear-gradient(180deg, rgba(255, 255, 255, .045), rgba(255, 255, 255, 0) 150px);
  --clay-glow: radial-gradient(1200px 560px at 20% -14%, rgba(32, 96, 188, .13), transparent 64%);

  --theme-link-color: var(--clay-accent-text);
  --theme-editbox-focus-border: var(--clay-accent);
  --theme-toggle-on-bg-color: var(--clay-accent);
  --theme-toggle-on-bg-hover: var(--clay-accent-hover);
  --global-accent-BackgroundColor: var(--clay-accent);
  --global-accent-TextColor: var(--clay-accent-text);
  --global-primary-LinkColor: var(--clay-accent-text);
  --global-focus-BorderColor: var(--clay-accent);
  --theme-tablist-plain-color: var(--clay-accent);
  --theme-popup-shadow: var(--clay-shadow-3), var(--clay-lit);
}


/* -----------------------------------------------------------------------------
 * 4. Typography and global feel
 * -------------------------------------------------------------------------- */

/* Issue ids, counters, estimates and dates sit in columns and change in place.
   Proportional figures make them jitter; lining figures cost nothing. */
body {
  font-feature-settings: "tnum" 1;
  letter-spacing: .006em;
}

.antiTable-cells,
.antiList-cells,
.hulyNavItem-count,
.hulyAccordionItem-header__counter,
.antiSection-header__counter,
.issuePresenter,
.hulyTaskNavLink-container,
.estimation-container {
  font-variant-numeric: tabular-nums !important;
}

/* Scrollbars recede: a hard grey bar fights every matte surface next to it. */
::-webkit-scrollbar { width: 10px !important; height: 10px !important; }
::-webkit-scrollbar-thumb {
  border-radius: 99px !important;
  border: 3px solid transparent !important;
  background-clip: content-box !important;
}
html.theme-dark ::-webkit-scrollbar-thumb { background-color: rgba(165, 189, 255, .16) !important; }
html.theme-dark ::-webkit-scrollbar-thumb:hover { background-color: rgba(165, 189, 255, .30) !important; }
html.theme-light ::-webkit-scrollbar-thumb { background-color: rgba(23, 32, 56, .16) !important; }
html.theme-light ::-webkit-scrollbar-thumb:hover { background-color: rgba(23, 32, 56, .30) !important; }
::-webkit-scrollbar-corner { background-color: transparent !important; }

.scroller-container .bar { border-radius: 99px !important; }

/* Keyboard focus reads as a soft halo instead of a hard outline. Scoped to
   actual controls -- a blanket :focus-visible would ring scroll containers
   and the rich-text editor, which take focus but are not controls. */
button:focus-visible,
a:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
.antiButton:focus-visible,
.hulyButton:focus-visible {
  outline: none !important;
  box-shadow: var(--clay-ring) !important;
}

/* -----------------------------------------------------------------------------
 * 5. Shell -- status bar, app rail, navigator, content slab
 *
 * The navigator and the content area become two clay slabs lifted off the
 * canvas. The gap lives as padding on their shared flex parent, so each panel
 * keeps its own width and its own drag-to-resize behaviour untouched.
 * -------------------------------------------------------------------------- */

.antiStatusBar {
  background: var(--theme-back-color) !important;
  border-bottom: none !important;
}

.antiPanel-application {
  background: var(--theme-back-color) !important;
  border: none !important;
}

.workbench-container.apps-vertical {
  background-color: var(--theme-back-color) !important;
  background-image: var(--clay-glow) !important;
}

.workbench-container.inner {
  padding: var(--clay-gap) var(--clay-gap) var(--clay-gap) 0 !important;
  gap: var(--clay-gap) !important;
  background: transparent !important;
}

.antiPanel-navigator {
  border: none !important;
  background: transparent !important;
}

.hulyNavPanel-container,
.antiPanel-navigator > .antiPanel-wrap__content {
  background: var(--clay-sheen-slab), var(--theme-navpanel-color) !important;
  border: none !important;
  border-radius: var(--clay-r-xl) !important;
  box-shadow: var(--clay-shadow-1), var(--clay-lit), var(--clay-shade) !important;
  overflow: hidden !important;
}

.hulyComponent {
  background: var(--clay-sheen-slab), var(--theme-panel-color) !important;
  border: none !important;
  border-radius: var(--clay-r-xl) !important;
  box-shadow: var(--clay-shadow-2), var(--clay-lit), var(--clay-shade) !important;
}

.hulySidePanel-container {
  background: var(--clay-sheen-slab), var(--theme-panel-color) !important;
  border: none !important;
  border-radius: var(--clay-r-xl) !important;
  box-shadow: var(--clay-shadow-2), var(--clay-lit), var(--clay-shade) !important;
  overflow: hidden !important;
}

.hulyHeader-container {
  background: transparent !important;
  border-bottom: 1px solid var(--theme-divider-color) !important;
}

.hulyHeader-divider,
.hulyHeader-row__divider { background: var(--theme-divider-color) !important; }

/* Still grabbable, just no longer drawn -- the canvas gap separates the panels. */
.antiSeparator { background: transparent !important; }

/* -----------------------------------------------------------------------------
 * 6. Navigation
 * -------------------------------------------------------------------------- */

.hulyNavItem-container,
.antiNav-element,
.hulyNavGroup-header {
  border-radius: var(--clay-r-md) !important;
  transition: background var(--clay-fast), box-shadow var(--clay-fast), color var(--clay-fast) !important;
}

.hulyNavItem-container:hover,
.antiNav-element:hover { background-color: var(--theme-navpanel-hovered) !important; }

.hulyNavItem-container.selected,
.antiNav-element.selected {
  background-color: var(--theme-navpanel-selected) !important;
  background-image: var(--clay-sheen) !important;
  box-shadow: var(--clay-lit), var(--clay-shade), var(--clay-shadow-1) !important;
}

.hulyNavItem-count { border-radius: 99px !important; font-variant-numeric: tabular-nums !important; }

.antiNav-divider.line,
.antiNav-footer-line { background: var(--theme-divider-color) !important; }

/* The active app is a well pressed into the rail rather than a raised tile --
   inverting the direction is what separates "here" from "clickable". */
.antiPanel-application .app {
  border-radius: var(--clay-r-md) !important;
  transition: background var(--clay-fast), box-shadow var(--clay-fast) !important;
}
.antiPanel-application .app.active,
.antiPanel-application .app.selected { box-shadow: var(--clay-press) !important; }

/* -----------------------------------------------------------------------------
 * 7. Buttons
 * -------------------------------------------------------------------------- */

.antiButton,
.hulyButton,
.hulySplitButton-container {
  border-radius: var(--clay-r-md) !important;
  transition:
    background var(--clay-fast),
    box-shadow var(--clay-fast),
    border-color var(--clay-fast),
    transform var(--clay-fast) !important;
}

/* Stock shape modifiers, normalised onto the clay scale so no button stays
   sharp-cornered beside a rounded neighbour. */
.antiButton.sh-round, .antiButton.sh-round-sm, .antiButton.sh-round-md,
.hulyButton.round, .hulyButton.round-small { border-radius: var(--clay-r-lg) !important; }
.antiButton.sh-circle, .hulyButton.circle { border-radius: 50% !important; }
.antiButton.sh-rectangle-right, .hulyButton.rectangle-right {
  border-radius: var(--clay-r-md) 0 0 var(--clay-r-md) !important;
}
.antiButton.sh-rectangle-left, .hulyButton.rectangle-left {
  border-radius: 0 var(--clay-r-md) var(--clay-r-md) 0 !important;
}

/* Only solid buttons are raised. Ghost and link buttons stay flat on purpose:
   if everything is lifted, nothing reads as lifted. */
.antiButton.bs-solid,
.antiButton.regular,
.antiButton.secondary,
.hulyButton.secondary,
.hulyButton.tertiary {
  box-shadow: var(--clay-lit), var(--clay-shade), var(--clay-shadow-1) !important;
}

.antiButton.dangerous,
.hulyButton.negative {
  box-shadow: var(--clay-lit), var(--clay-shade), var(--clay-shadow-1) !important;
}

/* The top-lit falloff, painted over whatever colour the button already has.
   background-image (not background) so every variant keeps its own fill.
   .attention is excluded -- it ships a deliberate brand gradient of its own. */
.antiButton.bs-solid:not(.attention),
.antiButton.regular:not(.attention),
.antiButton.secondary:not(.attention),
.antiButton.dangerous:not(.attention),
.hulyButton.secondary:not(.attention),
.hulyButton.tertiary:not(.attention),
.hulyButton.negative:not(.attention) {
  background-image: var(--clay-sheen) !important;
}

/* The primary button is deliberately matte: flat fill, no sheen, no lit rim,
   no coloured glow. It is the one control that carries a saturated brand
   colour, and gloss on top of saturation is what tips a button from "solid"
   into "web graphic". Weight alone is enough to make it the primary action --
   everything around it is quiet. Hover and press are carried by the fill
   getting darker, which is what the --primary-button-* ramp already does. */
.antiButton.primary,
.hulyButton.primary,
.antiButton.primary:not(:disabled):not(.disabled):hover,
.hulyButton.primary:not(:disabled):not(.disabled):hover {
  background-image: none !important;
  box-shadow: none !important;
  transform: none;
}

/* 1px of lift on hover, settling flat on press. Cheapest possible way to make
   a surface feel physical -- transform and box-shadow only, no layout work. */
.antiButton:not(:disabled):not(.disabled):hover,
.hulyButton:not(:disabled):not(.disabled):hover {
  transform: translateY(-1px);
  box-shadow: var(--clay-lit), var(--clay-shade), var(--clay-shadow-2) !important;
}

.antiButton:not(:disabled):not(.disabled):active,
.hulyButton:not(:disabled):not(.disabled):active {
  transform: translateY(0);
  box-shadow: var(--clay-press) !important;
  transition-duration: 60ms !important;
}

.antiButton.ghost,
.antiButton.bs-none,
.hulyButton.ghost,
.hulyButton.list { box-shadow: none !important; }

.antiButton.ghost:hover,
.antiButton.bs-none:hover,
.hulyButton.ghost:hover { transform: none; box-shadow: none !important; }

.antiButton:disabled,
.antiButton.disabled,
.hulyButton:disabled { box-shadow: none !important; transform: none !important; }

/* Segmented controls (list/kanban switcher, tab strips): pressed track, one
   raised chip marking the selection. */
.switcher-container {
  border-radius: var(--clay-r-md) !important;
  padding: 2px !important;
  background: var(--theme-button-container-color) !important;
  box-shadow: var(--clay-press) !important;
}
.switcher-element {
  border-radius: calc(var(--clay-r-md) - 2px) !important;
  transition: background var(--clay-fast), box-shadow var(--clay-fast), color var(--clay-fast) !important;
}
.switcher-element.selected {
  background-image: var(--clay-sheen) !important;
  box-shadow: var(--clay-lit), var(--clay-shade), var(--clay-shadow-1) !important;
}

.hulyChip-item,
.chip,
.antiMention { border-radius: 99px !important; }

/* -----------------------------------------------------------------------------
 * 8. Inputs
 *
 * Fields are pressed *into* the surface, the exact inverse of a button. That
 * inversion is what makes "type here" and "click here" distinguishable without
 * reading either of them.
 * -------------------------------------------------------------------------- */

.antiEditBoxInput,
.searchInput-wrapper,
.antiSelect,
.ref-container,
.text-input,
.textInput {
  border-radius: var(--clay-r-sm) !important;
  transition: box-shadow var(--clay-fast), background var(--clay-fast), border-color var(--clay-fast) !important;
}

.searchInput-wrapper,
.antiSelect {
  border-color: transparent !important;
  box-shadow: var(--clay-press) !important;
}
.searchInput-wrapper:focus-within { box-shadow: var(--clay-press), var(--clay-ring) !important; }

/* Comment / description composer. */
.ref-container {
  border-radius: var(--clay-r-lg) !important;
  border-color: transparent !important;
  box-shadow: var(--clay-press) !important;
}
.ref-container:focus-within { box-shadow: var(--clay-press), var(--clay-ring) !important; }

/* The frame around an edit box is drawn by the .focusable wrapper, not by the
   .antiEditBoxInput inside it, so the radius above never reached it. Worse,
   the wrapper is fully transparent until focused: no fill, no border. A field
   nobody can see until they click it is not a field, and next to the
   description box -- which had its own faint outline -- the two read as
   unrelated controls on the same card.

   Give it the resting state every other input in this section has: the same
   fill as a button, pressed in rather than raised. That inversion is the whole
   idea of section 8, and it is what makes "type here" legible at rest. */
.antiEditBox.focusable,
.antiEditBox .focusable {
  border-radius: var(--clay-r-sm) !important;
  padding-left: .75rem !important;
  padding-right: .75rem !important;
  background-color: var(--theme-button-default) !important;
  box-shadow: var(--clay-press) !important;
  /* Stacked fields sit edge to edge -- location and participants in the event
     dialog share a boundary exactly, which did not matter while both were
     transparent but merges them into one blob now that each has a body. 3px a
     side puts 6px between neighbours, which is also what keeps the 3px focus
     ring below from landing on the field underneath. */
  margin-top: .1875rem !important;
  margin-bottom: .1875rem !important;
}

/* Focus keeps the accent, as a ring around the field rather than a wash across
   it. Huly fills the box with the accent at 45%, which on the light palette
   turns the field into a solid coloured slab -- a button's job, and the one
   thing this section exists to distinguish it from. */
.antiEditBox.focusable:focus-within,
.antiEditBox .focusable:focus-within {
  background-color: var(--theme-button-default) !important;
  box-shadow: var(--clay-press), var(--clay-ring) !important;
}

/* The caret is drawn in the input's `color`, and Huly gives a `ghost` edit box
   no colour of its own -- it inherits whatever the popup around it happens to
   set, which in the dark palette is the dim body colour. A dim 1px bar on a
   field that is now pressed in, with a 6px blurred inset along its edges, is a
   caret you cannot find: it blinks somewhere inside the shadow. Name both the
   text and the caret explicitly, in the brightest text colour the theme has --
   the same colour `ghost-large` already asks for. */
/* Two shapes, one field: a plain EditBox puts `.focusable` on a div inside
   `.antiEditBox`, while the participants field is an `.antiEditBox.ghost` that
   carries `.focusable` itself. Missing the second is why this rule did nothing
   for that field. */
.antiEditBox.focusable .antiEditBoxInput,
.antiEditBox.focusable input,
.antiEditBox .focusable .antiEditBoxInput,
.antiEditBox .focusable input {
  color: var(--theme-caption-color) !important;
  caret-color: var(--theme-caption-color) !important;
}

/* ...and the input inside it must not draw a ring of its own. Section 4 rings
   every focused input, which is right for a bare one but doubles up here: the
   input is inset from the frame by its padding, so its ring traces a second,
   smaller outline a few pixels inside the first. The wrapper is the thing that
   looks like the field, so the wrapper keeps the ring. */
.antiEditBox.focusable input:focus-visible,
.antiEditBox .focusable input:focus-visible {
  box-shadow: none !important;
}

/* Same problem, other end: on the light palette --clay-press is a 9%-alpha
   inset over a white card, which is not enough of an edge to read as a field
   at all. Give it a body of its own, the same one the edit box above now has,
   so the two match. */
.ref-container {
  background-color: var(--theme-button-default) !important;
}

/* Huly reserves 40px at the left of an editor for the hover menu that inserts
   blocks. The menu is positioned against .ref-container, NOT against this
   padding, so shrinking the gutter does not move it -- it just slides the text
   underneath it, and the "+" lands on the first word. Left alone at 40px.

   The right side had no padding at all, which is the half of it that really
   was crooked: text 40px from one edge and flush against the other, inside a
   symmetric rounded frame. Scoped through :has() to compact editors; a browser
   without :has() drops the rule and keeps stock behaviour. */
.ref-container .select-text:has(> .text-editor-view_compact) {
  padding-right: .75rem !important;
}

/* That same menu is a 20px square pinned to the editor's first line, and
   Huly's 8.5px offset is measured for the full-size editor's taller line box.
   The compact editor's line is 21px, so the offset drops the "+" 8px below the
   word it belongs to. Centre it on the line instead: (line - 20) / 2, with the
   line written as 1.5em because 1.5 is this editor's line-height -- so the
   centring survives a font-size change rather than being a magic 0.5px. */
.ref-container .select-text:has(> .text-editor-view_compact) > .tiptap-left-menu {
  top: calc((1.5em - 20px) / 2) !important;
}

/* -----------------------------------------------------------------------------
 * 9. Lists, tables, cards
 * -------------------------------------------------------------------------- */

.list-container {
  border-radius: var(--clay-r-lg) !important;
  border-color: transparent !important;
  overflow: hidden !important;
  background-image: var(--clay-sheen-slab) !important;
  box-shadow: var(--clay-shadow-1), var(--clay-lit), var(--clay-shade) !important;
}

.antiList__row,
.antiTable-body__row {
  transition: background var(--clay-fast), box-shadow var(--clay-fast) !important;
}
.antiList__row:hover,
.antiTable-body__row:hover { background: var(--theme-navpanel-hovered) !important; }

.antiTable { border-radius: var(--clay-r-lg) !important; overflow: hidden !important; }
.antiTable th { background: var(--theme-table-header-color) !important; }

/* Kanban cards are the one place where a card genuinely floats and gets
   dragged, so they earn the full slab and a real lift on hover. */
.kanban-card,
.card-container {
  border-radius: var(--clay-r-lg) !important;
  border: none !important;
  background: var(--clay-sheen), var(--theme-kanban-card-bg-color) !important;
  box-shadow: var(--clay-lit), var(--clay-shade), var(--clay-shadow-1) !important;
  transition: box-shadow var(--clay-slow), transform var(--clay-slow) !important;
}
.kanban-card:hover,
.card-container:hover {
  transform: translateY(-2px);
  box-shadow: var(--clay-lit), var(--clay-shade), var(--clay-shadow-2) !important;
}

.attachment-container,
.attachment-grid > * { border-radius: var(--clay-r-md) !important; }

.activityMessage { border-radius: var(--clay-r-md) !important; }

/* Pasted screenshots are most of what a ticket description contains here, and
   a hard-cornered image in a fully rounded page is the one element that gives
   the whole thing away. */
.text-editor-view img,
.text-editor-view video { border-radius: var(--clay-r-md) !important; }

/* -----------------------------------------------------------------------------
 * 10. Popups, modals, panels
 *
 * .antiPopup itself is deliberately left alone: it carries no background of
 * its own (each popup component paints its own via a scoped rule), so adding
 * a border or shadow here would draw a frame around thin air. The elevation
 * reaches all of them through --theme-popup-shadow above instead.
 * -------------------------------------------------------------------------- */

.antiPopup,
.selectPopup,
.hulyPopup-container,
.antiPopup-submenu,
.notifyPopup { border-radius: var(--clay-r-lg) !important; }

.menu-item,
.hulyPopup-row {
  border-radius: var(--clay-r-sm) !important;
  transition: background var(--clay-fast) !important;
}

.antiCard,
.hulyModal-container,
.antiDialog {
  border-radius: var(--clay-r-xl) !important;
  border: none !important;
  overflow: hidden !important;
  background-image: var(--clay-sheen-slab) !important;
}

.antiPanel {
  border-radius: var(--clay-r-xl) !important;
  background-image: var(--clay-sheen-slab) !important;
}

/* Dimming the app behind a modal also softens it -- a blurred backdrop is what
   sells the modal as physically nearer rather than merely on top. */
.antiOverlay { backdrop-filter: blur(3px) saturate(.9); }

/* Bottom-right only. The attribute column starts below the panel header and
   runs to the bottom edge, so rounding its top corner cuts a notch into the
   middle of the panel edge instead of following it. */
.popupPanel-body__aside { border-radius: 0 0 var(--clay-r-xl) 0 !important; }

.popup-tooltip { border-radius: var(--clay-r-sm) !important; box-shadow: var(--clay-shadow-2) !important; }

/* The one control this theme removes rather than restyles.
 *
 * "Создать встречу" in the event dialog books a video room from the `love`
 * service. That service is not deployed here: compose defines no `love`
 * container, its nginx block is commented out, and the front is still handed a
 * LOVE_ENDPOINT -- so the front asks /_love/checkRecordAvailable, nginx falls
 * through to the SPA and answers with index.html, and the client throws
 * "Unexpected token '<'". Ticking the box cannot produce a room. Calls happen
 * in Telemost instead, so the checkbox is an offer the app cannot keep.
 *
 * Matched by shape, not text: this is the only .block in the dialog carrying a
 * checkbox, and .block itself is shared by every row. A browser without :has()
 * drops the rule and shows the checkbox again -- harmless, since it is inert
 * either way.
 *
 * The real fix is dropping LOVE_ENDPOINT from the front's environment in
 * compose.yml, which would also stop the failing request; that is a front
 * container restart rather than an nginx reload, hence not done here.
 * -------------------------------------------------------------------------- */

.eventPopup-container .block:has(> .flex-row-center > label.checkbox-container) {
  display: none !important;
}

/* Location. Nothing here is booked by address -- the room is a Telemost link
   in the description, and the field was one more empty box between the time
   and the people.

   Matched by shape, and the shape had to be read off the version actually
   deployed: this front is 0.7, where `.container` sits on the *participants*
   row and the location row is the bare one. The first version of this rule was
   written against 0.6, where it is the other way round, and it hid the
   participants -- the one row in this dialog that must not go.

   So: inside the row-pair that contains participants, hide the sibling that is
   not participants. Scoping through `:has()` keeps it away from the block
   below, whose first row (the calendar selector) looks the same from here. */
.eventPopup-container .block:has(> .flex-row-center.flex-gap-1.container)
  > .flex-row-center.flex-gap-1:not(.container) {
  display: none !important;
}

/* "Add guest" beside the participants field. A guest is a contact created
   outside the workspace: the server copies a new event into a participant's
   own calendar only when that participant has an account here (see
   onEventCreate in server-plugins/calendar-resources), so a guest is added to
   the event and then never told about it. Meetings here are with the company,
   so the field keeps only what the search finds -- people who actually have an
   account -- and the button that makes non-members goes.

   The participants field is the only place in this dialog where a `.tool` sits
   directly inside a full-width `.container` under an `.antiEditBox`. The
   location row has a `.tool` of its own -- the "open link" arrow -- but it
   hangs off a plain `.container` instead, so this leaves it alone. */
.eventPopup-container .antiEditBox > .flex-row-center.w-full.container > .tool {
  display: none !important;
}

/* The "pick from the list" control under the participants field, and the panel
   it opens; both are built by decorateEventPopup in clay.js. The panel is an
   ordinary block in the dialog rather than a floating popup: the dialog is
   narrow and already scrolls, and a floating layer over it would fight both
   Huly's own suggestion popup and the scroll. */
.clay-pickbtn {
  display: block;
  margin: .125rem 0 .375rem 1.5rem;
  padding: .1875rem .5rem;
  border: none;
  border-radius: var(--clay-r-sm);
  background-color: var(--theme-button-default);
  box-shadow: var(--clay-lit), var(--clay-shade);
  color: var(--theme-content-color);
  font-family: inherit;
  font-size: .75rem;
  line-height: 1rem;
  cursor: pointer;
  transition: color var(--clay-fast), box-shadow var(--clay-fast);
}
.clay-pickbtn:hover {
  color: var(--theme-caption-color);
  box-shadow: var(--clay-lit), var(--clay-shade), var(--clay-shadow-1);
}
.clay-pickbtn:active { box-shadow: var(--clay-press); }

.clay-picker {
  margin: 0 0 .5rem 1.5rem;
  padding: .375rem;
  border-radius: var(--clay-r-sm);
  background-color: var(--theme-button-default);
  box-shadow: var(--clay-press);
}

.clay-picker--loading,
.clay-picker--failed {
  padding: .5rem;
  font-size: .75rem;
  line-height: 1rem;
  color: var(--theme-darker-color);
}

.clay-picker__search {
  width: 100%;
  margin-bottom: .25rem;
  padding: .25rem .5rem;
  border: none;
  border-radius: var(--clay-r-sm);
  background-color: var(--theme-popup-color);
  color: var(--theme-caption-color);
  caret-color: var(--theme-caption-color);
  font-family: inherit;
  font-size: .8125rem;
}
.clay-picker__search:focus-visible { outline: none; box-shadow: var(--clay-ring); }

/* Huly's own participants field while the panel is open. Collapsed to nothing
   rather than `display: none`, because adding a participant still types into
   it and focuses it first, and a field that is not displayed cannot be
   focused. Everything here is geometry and paint -- nothing that would take it
   out of the document. */
.clay-pickrow--away {
  height: 0;
  min-height: 0;
  margin: 0;
  padding: 0;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}

/* Ten-ish rows before it scrolls: enough to see the team at a glance, short
   enough to leave the rest of the dialog visible. */
.clay-picker__list {
  max-height: 13rem;
  overflow-y: auto;
}

.clay-picker__row {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .1875rem .375rem;
  border-radius: var(--clay-r-sm);
  font-size: .8125rem;
  line-height: 1.25rem;
  color: var(--theme-content-color);
  cursor: pointer;
}
.clay-picker__row:hover { background-color: var(--theme-button-hovered); color: var(--theme-caption-color); }
.clay-picker__row input { accent-color: var(--primary-button-default); cursor: pointer; }
.clay-picker__row input:disabled { cursor: progress; }
/* Filtering the list hides rows with the `hidden` attribute, and `display: flex`
   above would quietly win: an author rule beats the browser's own
   `[hidden] { display: none }` whatever its specificity. Without this the
   attribute was set on every filtered-out row and not one of them moved. */
.clay-picker__row[hidden] { display: none; }

.clay-picker__footer {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding-top: .375rem;
}

/* The confirmation. Disabled until a box disagrees with the event, so the
   button is also the answer to "did my tick register?". */
.clay-picker__apply {
  flex-shrink: 0;
  padding: .1875rem .625rem;
  border: none;
  border-radius: var(--clay-r-sm);
  background-color: var(--primary-button-default);
  box-shadow: var(--clay-lit), var(--clay-shade);
  color: var(--primary-button-color);
  font-family: inherit;
  font-size: .75rem;
  line-height: 1rem;
  cursor: pointer;
  transition: box-shadow var(--clay-fast), opacity var(--clay-fast);
}
.clay-picker__apply:hover:not(:disabled) {
  box-shadow: var(--clay-lit), var(--clay-shade), var(--clay-shadow-1);
}
.clay-picker__apply:active:not(:disabled) { box-shadow: var(--clay-press); }
.clay-picker__apply:disabled {
  background-color: var(--theme-button-default);
  color: var(--theme-darker-color);
  box-shadow: var(--clay-press);
  cursor: default;
}

.clay-picker__status:empty { display: none; }
.clay-picker__status {
  padding: 0 .125rem;
  font-size: .75rem;
  line-height: 1rem;
  color: var(--theme-darker-color);
}

/* -----------------------------------------------------------------------------
 * 11. Small parts
 * -------------------------------------------------------------------------- */

.antiSection,
.antiAccordion,
.hulyAccordionItem-container,
.hulyTableAttr-container { border-radius: var(--clay-r-lg) !important; }

.antiDivider { border-color: var(--theme-divider-color) !important; }

.checkbox,
.checkbox-element { border-radius: var(--clay-r-xs) !important; }

.toggle-switch { box-shadow: var(--clay-shadow-1) !important; }

.progress-bar { border-radius: 99px !important; overflow: hidden !important; }

/* -----------------------------------------------------------------------------
 * 12. Motion opt-out
 *
 * Everything above that moves is a transform, so honouring the OS setting is
 * a matter of switching the transitions off rather than redesigning anything.
 * -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .antiButton, .hulyButton, .kanban-card, .card-container,
  .hulyNavItem-container, .antiNav-element, .switcher-element {
    transition: none !important;
  }
  .antiButton:hover, .hulyButton:hover,
  .kanban-card:hover, .card-container:hover { transform: none !important; }
  .clay-fold svg, .clay-more, .clay-plan { transition: none !important; }
  .clay-more:hover, .clay-plan:hover { transform: none !important; }
}

/* -----------------------------------------------------------------------------
 * 13. Behaviour layer
 *
 * Styling for the elements theme/clay.js adds. The script only ever toggles
 * classes; all of the actual hiding happens here, which means deleting this
 * section is enough to see the stock layout again.
 * -------------------------------------------------------------------------- */

/* --- Activity fold ------------------------------------------------------- */

.clay-activity.clay-collapsed .p-activity { display: none !important; }

.clay-fold {
  display: flex;
  align-items: center;
  gap: .25rem;
  flex-shrink: 0;
  margin-right: .25rem;
  padding: .125rem .25rem;
  border: none;
  border-radius: var(--clay-r-xs);
  background: transparent;
  color: var(--theme-dark-color);
  cursor: pointer;
  transition: background var(--clay-fast), color var(--clay-fast);
}
.clay-fold:hover {
  background: var(--theme-button-hovered);
  color: var(--theme-caption-color);
}
.clay-fold svg {
  transition: transform var(--clay-fast);
}
/* Chevron points right while folded, down once open -- the direction is the
   only affordance saying the section can be opened at all. */
.clay-activity:not(.clay-collapsed) .clay-fold svg { transform: rotate(90deg); }

.clay-fold__count {
  min-width: 1.25rem;
  padding: 0 .3rem;
  border-radius: 99px;
  background: var(--theme-navpanel-selected);
  color: var(--theme-dark-color);
  font-size: .6875rem;
  line-height: 1rem;
  font-variant-numeric: tabular-nums;
  text-align: center;
}
/* A count of nothing is noise, and an empty pill is worse than no pill. */
.clay-fold__count:empty { display: none; }

/* --- Compact attribute column -------------------------------------------- */

.clay-aside-compact .clay-extra { display: none !important; }

/* A footer control under the column, not a field among the fields. Full width
   and centred so it reads as "the end of the list", which is exactly what it
   marks. */
.clay-more {
  display: block;
  width: 100%;
  margin: .5rem 0 .25rem;
  padding: .5rem .75rem;
  border: none;
  border-radius: var(--clay-r-sm);
  background: transparent;
  color: var(--theme-dark-color);
  font-family: inherit;
  font-size: .75rem;
  letter-spacing: .01em;
  text-align: center;
  cursor: pointer;
  transition: background var(--clay-fast), box-shadow var(--clay-fast),
              color var(--clay-fast), transform var(--clay-fast);
}
.clay-more:hover {
  background-color: var(--theme-button-default);
  background-image: var(--clay-sheen);
  box-shadow: var(--clay-lit), var(--clay-shade), var(--clay-shadow-1);
  color: var(--theme-caption-color);
  transform: translateY(-1px);
}
.clay-more:active {
  box-shadow: var(--clay-press);
  transform: translateY(0);
}

/* --- Planner: "Запланировать" and "Встречи" ------------------------------- */

/* Their own row between the date and the to-do input. The to-do column is
   narrow and its header is mostly a long localised date, so there is no room
   beside it -- see the note on buildPlannerBar in clay.js. */
.clay-planbar {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .625rem .75rem .75rem;
}

.clay-plan {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .375rem;
  height: 1.875rem;
  padding: 0 .75rem;
  border: none;
  border-radius: var(--clay-r-sm);
  font-family: inherit;
  font-size: .8125rem;
  font-weight: 500;
  letter-spacing: .01em;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--clay-fast), box-shadow var(--clay-fast),
              color var(--clay-fast), transform var(--clay-fast);
}

.clay-plan__icon { display: inline-flex; align-items: center; opacity: .85; }

.clay-plan:active {
  box-shadow: var(--clay-press);
  transform: translateY(0);
  transition-duration: 60ms;
}

/* Matte like every other primary button in section 7: flat fill, no sheen, no
   glow. It takes the free width because it is the action, not the toggle. */
.clay-plan--schedule {
  flex: 1 1 auto;
  background-color: var(--primary-button-default);
  background-image: none;
  color: var(--primary-button-color, #fff);
}
.clay-plan--schedule:hover {
  background-color: var(--primary-button-hovered);
  transform: translateY(-1px);
}
.clay-plan--schedule:active { background-color: var(--primary-button-pressed); }

.clay-plan--meetings {
  flex: 0 0 auto;
  background-color: var(--theme-button-default);
  background-image: var(--clay-sheen);
  color: var(--theme-content-color);
  box-shadow: var(--clay-lit), var(--clay-shade);
}
.clay-plan--meetings:hover {
  color: var(--theme-caption-color);
  transform: translateY(-1px);
  box-shadow: var(--clay-lit), var(--clay-shade), var(--clay-shadow-1);
}

/* Pressed-in while its panel is showing -- the same inversion the app rail
   uses for the active app, so "open" reads the same way in both places. */
.clay-plan--meetings.clay-plan--on {
  background-color: var(--theme-navpanel-selected);
  background-image: none;
  color: var(--theme-caption-color);
  box-shadow: var(--clay-press);
  transform: none;
}

/* The sidebar meetings panel is a full calendar of its own, so the Planner's
   single-day grid steps aside while it is open rather than sitting beside it
   as a second, narrower copy. Toggled by syncPlannerGrid in clay.js; the
   element is only hidden, never removed. */
.clay-planner-grid--off { display: none !important; }


/* -----------------------------------------------------------------------------
 * 14. Legibility -- redesign P0
 *
 * Three fixes from the redesign audit that live entirely in CSS. Each one was
 * checked against the rule it overrides, read out of the shipped bundle rather
 * than guessed, and each degrades to "stock" if a version bump moves the class.
 *
 * Two audit findings are deliberately NOT here, because measuring them said
 * there was nothing to fix:
 *
 *   - Priority is not colour-only. The stock icons are different shapes
 *     (urgent is a filled badge, the rest are bar charts of rising height),
 *     so hue is already the second channel, not the only one.
 *   - Dark-theme secondary text is not too faint. Every level of both ramps
 *     clears 4.5:1 on Nord's dark surfaces; the weakest, --theme-darker-color,
 *     measures 4.07:1 on a list row. The light variant was the one that was
 *     short -- fixed in the palette block above.
 *   - The row of small round buttons under the description measures 32x32.
 *     It reads as cluttered because six equal circles carry no hierarchy, not
 *     because anything is hard to hit; naming the important ones is a front
 *     change, not a CSS one.
 *
 * And one that cannot be done here at all: the issue title is an `<input>`
 * (`.antiEditBoxInput` at 20px, inside `.large-style`), so it clips instead of
 * wrapping and no stylesheet can make it three lines. Full titles need the
 * front to render that EditBox multiline.
 * -------------------------------------------------------------------------- */

/* Project names read as names, not as shouting.
 *
 * Stock: `.hulyNavGroup-container .hulyNavGroup-header__label` is uppercased
 * and painted with the tertiary token -- the weakest text level there is. A
 * navigator holding twelve projects is therefore twelve blocks of dim capitals
 * that have to be spelled out rather than recognised, and "ГЕРМЕС ПОДДЕРЖКА/IT
 * TICKETS" is the worst case of it. The names are mixed case in the data --
 * "Гермес Поддержка/IT Tickets", emoji and all -- so this restores what was
 * typed rather than inventing a style.
 *
 * `.nested` is doing real work in that selector and must not be dropped: the
 * "ПРОЕКТЫ" caption above the list is the SAME class, sitting in a
 * `.hulyNavGroup-container.noIcon` instead. There the capitals are correct --
 * they mean "section heading" -- and an unscoped rule lowercases it too. */
.hulyNavGroup-container.nested .hulyNavGroup-header__label {
  text-transform: none !important;
  letter-spacing: 0 !important;
  color: var(--global-secondary-TextColor) !important;
}

/* The open project is worth seeing from across the room. Stock separates it
   from its neighbours with a background two steps off the panel colour, which
   is one weak channel doing the whole job; a bar at the leading edge adds a
   second one that survives both a glance and a colour-blind eye.
 *
 * The class is `.highlighted`, not `.selected` -- `.selected` lives on the
 * `.hulyNavItem-container` row inside the group ("Задачи"), never on the
 * project header. `.highlighted` means "contains the current selection",
 * which the PROJECTS caption also carries, so this needs `.nested` and the
 * direct-child combinator to land on the project alone. */
.hulyNavGroup-container.nested > .hulyNavGroup-header.highlighted {
  box-shadow: inset 2px 0 0 var(--clay-accent-text) !important;
}

/* Overdue stops being colour and nothing else.
 *
 * Stock paints `.btn-icon.overdue` with --theme-error-color and changes
 * nothing else: same chip, same shape, same label. That is the exact case
 * WCAG 1.4.1 is about -- on a dim screen, or for the ~8% of men who cannot
 * separate that red from the neutral, an overdue date and an ordinary one are
 * the same object. A warning sign in front of the date carries the meaning
 * without depending on hue, and a wash behind the chip makes it findable while
 * scanning a list.
 *
 * The marker hangs off the button, not off a `.label` inside it: measured on
 * a live issue, the date is a bare text node and `.label` is not there at all
 * (`<button class="datetime-button …"><div class="btn-icon overdue">svg</div>
 * 5 авг.</button>`). As the button's own ::before it becomes the first flex
 * item and lands ahead of the calendar glyph, which is where a warning
 * belongs. Every overdue chip on the page grew from 73px to 86px when this
 * was probed, so it reaches all of them and not just the labelled ones.
 *
 * color-mix keeps the wash tied to whatever --theme-error-color the live
 * palette sets, so this rule does not need a per-variant copy. */
.datetime-button:has(.btn-icon.overdue)::before,
.datetime-button:has(.btn-icon.critical)::before {
  /* Escaped rather than literal: `location = /clay.css` sends `text/css` with
     no charset, so the browser decodes the file with the document's encoding.
     That is UTF-8 today and the literal character would survive -- but a CSS
     escape cannot be decoded wrongly by anything, and this is the only
     non-ASCII glyph the stylesheet renders. \00A0 is a non-breaking space;
     a plain one would be eaten as the escape's terminator. */
  content: "\26A0\00A0";
  font-size: .9em;
  color: var(--theme-error-color);
}

.datetime-button:has(.btn-icon.overdue) {
  background-color: color-mix(in srgb, var(--theme-error-color) 13%, transparent) !important;
}

/* Hit areas, grown without moving anything.
 *
 * WCAG 2.5.8 asks for 24x24 CSS px. Measured on a live issue, almost
 * everything already clears it -- the editor toolbar buttons people call
 * "все эти кружочки" are a comfortable 32x32, and the status and list
 * buttons are 28x28. Three controls do not:
 *
 *   .hulyNavGroup-header__chevron  20x20, and there are twelve of them
 *   .clay-fold                     22x18 -- ours, the activity toggle
 *   .scrollArrow                   16x32, too narrow
 *
 * Growing the boxes would push their neighbours around, so the click area
 * grows instead: a transparent ::after bleeding 4px past each edge belongs
 * to the button and takes its clicks, while layout sees nothing. `inset`
 * needs the parent to be positioned, hence the `position: relative`.
 *
 * Deliberately not touched: `.updown-up` / `.updown-down` in the date popup,
 * 16x8 each and stacked directly on top of one another. Bleeding those out
 * would make each one cover half of the other, so "down" would start
 * registering as "up" -- worse than the small target. They need a real fix
 * in the component. */
.hulyNavGroup-header__chevron,
.clay-fold,
.scrollArrow {
  position: relative !important;
}

.hulyNavGroup-header__chevron::after,
.clay-fold::after,
.scrollArrow::after {
  content: "" !important;
  position: absolute !important;
  inset: -4px !important;
}
