/* ===========================================================================
   Personalize — the v3 skin's palette, as data attributes on <html>.

   landing.css draws every piece of the v3 skin from a handful of custom
   properties, and this file does nothing but redefine them. A choice made
   here therefore restyles the whole site without a single component knowing
   about it, and a new colour is a block below plus a button in
   main/v3/includes/components/personalize.html.

   Three groups, one per column UserSetting keeps for this skin:

     data-v3-brand   -> UserSetting.v3_brand   (the whole palette)
     data-v3-page    -> UserSetting.v3_page    (how the page sits behind it)
     data-v3-rail    -> UserSetting.v3_rail    (the sidebar)

   **A brand is a palette, not an accent.** It was an accent once, and that is
   why picking rose used to give a pink button on a green page with a green
   sidebar: the neutrals — the page, the cards, the rules, the text and the
   rail — stayed the ones landing.css declares for the site's own green, and
   in the dark those *are* most of what you see. Every brand below therefore
   carries the full set, generated at the same lightness and chroma the green
   uses and rotated to its own hue. That is what keeps them harmonious with
   each other and legible in the same places: ink on page stays around 15:1
   and white on brand around 3.5:1 whichever one is picked.

   Order matters and is deliberate. A brand sets the neutrals; the page group
   below it may override them, because it is the reader saying something more
   specific; the rails come last for the same reason. The desk palettes
   (.panel-shell.theme-* in landing.css) beat all of it by being on an inner
   element — a desk's colour identifies the desk and is not a preference.

   Dark mode is Bootstrap's own data-bs-theme, so each brand carries its
   dark half here rather than being picked twice.
   =========================================================================== */

/* --------------------------------------------------- brands — daylight ---- */

:root[data-v3-brand="green"] {
    --brand: #2f9e5e;
    --brand-dark: #1f7a45;
    --brand-darker: #14532d;
    --brand-soft: #e8f5ee;
    --brand-softer: #f2faf5;
    --brand-rgb: 47, 158, 94;
    --ink: #1b2a21;
    --ink-muted: #6b7a71;
    --surface: #ffffff;
    --line: #e6eee9;
    --page: #f6f8f7;
    --rail: #103921;
    --rail-deep: #103921;
    --accent: #5cc387;
}

:root[data-v3-brand="amber"] {
    --brand: #c07c22;
    --brand-dark: #a1651a;
    --brand-darker: #6f4410;
    --brand-soft: #fbeedb;
    --brand-softer: #fdf8f0;
    --brand-rgb: 192, 124, 34;
    --ink: #29231c;
    --ink-muted: #79736c;
    --surface: #ffffff;
    --line: #eeebe7;
    --page: #f8f7f6;
    --rail: #372712;
    --rail-deep: #372712;
    --accent: #d6a25e;
}

:root[data-v3-brand="violet"] {
    --brand: #6d4bd6;
    --brand-dark: #573bb0;
    --brand-darker: #3a2678;
    --brand-soft: #ece6fb;
    --brand-softer: #f6f3fd;
    --brand-rgb: 109, 75, 214;
    --ink: #1f1b2a;
    --ink-muted: #6f6b7a;
    --surface: #ffffff;
    --line: #e8e6ee;
    --page: #f7f6f8;
    --rail: #1a1039;
    --rail-deep: #1a1039;
    --accent: #a491de;
}

:root[data-v3-brand="blue"] {
    --brand: #1f6fd0;
    --brand-dark: #1857a6;
    --brand-darker: #0f3a70;
    --brand-soft: #e2edfb;
    --brand-softer: #f2f7fd;
    --brand-rgb: 31, 111, 208;
    --ink: #1b222a;
    --ink-muted: #6b727a;
    --surface: #ffffff;
    --line: #e6eaee;
    --page: #f6f7f8;
    --rail: #102339;
    --rail-deep: #102339;
    --accent: #659bdc;
}

:root[data-v3-brand="rose"] {
    --brand: #c2356b;
    --brand-dark: #9d2a56;
    --brand-darker: #6c1b39;
    --brand-soft: #fae3ec;
    --brand-softer: #fdf3f7;
    --brand-rgb: 194, 53, 107;
    --ink: #291c21;
    --ink-muted: #796c71;
    --surface: #ffffff;
    --line: #ede7e9;
    --page: #f8f6f7;
    --rail: #361320;
    --rail-deep: #361320;
    --accent: #d0789a;
}

:root[data-v3-brand="slate"] {
    --brand: #47566b;
    --brand-dark: #354152;
    --brand-darker: #222b36;
    --brand-soft: #e6eaef;
    --brand-softer: #f4f6f8;
    --brand-rgb: 71, 86, 107;
    --ink: #1f2226;
    --ink-muted: #6f7276;
    --surface: #ffffff;
    --line: #e8eaec;
    --page: #f7f7f8;
    --rail: #1b232d;
    --rail-deep: #1b232d;
    /* the tint that reads on the dark rail, as light as the other five
       palettes' (#6c7e97 was a mid tone: 2.5:1 for an icon on the rail) */
    --accent: #9aa9bd;
}

/* ------------------------------------------------------- brands — dark ---- */
/* In the dark the brand has to lift off the page rather than sit on it, so
   each one gets a lighter ramp — and, because a page, a card and a rule are
   most of the screen here, its own neutrals too. */

:root[data-bs-theme="dark"][data-v3-brand="green"] {
    --brand: #34ad68;
    --brand-dark: #2b9459;
    --brand-darker: #9ce0ba;
    --brand-soft: #1b3d2c;
    --brand-softer: #163023;
    --brand-rgb: 52, 173, 104;
    --ink: #e8f0eb;
    --ink-muted: #9db3a6;
    --line: #23392c;
    --surface: #14241b;
    --page: #0d1a12;
    --rail: #0a1710;
    --rail-deep: #0a1710;
    --accent: #6bc892;
}

:root[data-bs-theme="dark"][data-v3-brand="amber"] {
    --brand: #d9a054;
    --brand-dark: #c2882f;
    --brand-darker: #f0cb93;
    --brand-soft: #3a2c15;
    --brand-softer: #2c2210;
    --brand-rgb: 217, 160, 84;
    --ink: #f0ece8;
    --ink-muted: #b2a99e;
    --line: #382f24;
    --surface: #231d15;
    --page: #19140e;
    --rail: #16110b;
    --rail-deep: #16110b;
    --accent: #debd91;
}

:root[data-bs-theme="dark"][data-v3-brand="violet"] {
    --brand: #a78bfa;
    --brand-dark: #8b6ceb;
    --brand-darker: #cdbcfd;
    --brand-soft: #2d2350;
    --brand-softer: #241c42;
    --brand-rgb: 167, 139, 250;
    --ink: #eae8f0;
    --ink-muted: #a29db3;
    --line: #282339;
    --surface: #181424;
    --page: #100d1a;
    --rail: #0d0a17;
    --rail-deep: #0d0a17;
    --accent: #9b80ef;
}

:root[data-bs-theme="dark"][data-v3-brand="blue"] {
    --brand: #5fa3f0;
    --brand-dark: #3b85d8;
    --brand-darker: #a9cdf7;
    --brand-soft: #152943;
    --brand-softer: #101f33;
    --brand-rgb: 95, 163, 240;
    --ink: #e8ebf0;
    --ink-muted: #9da7b3;
    --line: #232d39;
    --surface: #141b24;
    --page: #0d131a;
    --rail: #0a1017;
    --rail-deep: #0a1017;
    --accent: #85b3ea;
}

:root[data-bs-theme="dark"][data-v3-brand="rose"] {
    --brand: #e0729c;
    --brand-dark: #c8567f;
    --brand-darker: #f3b6cd;
    --brand-soft: #3d1a2a;
    --brand-softer: #2e1420;
    --brand-rgb: 224, 114, 156;
    --ink: #efe8eb;
    --ink-muted: #b19fa6;
    --line: #37252c;
    --surface: #23151a;
    --page: #190e12;
    --rail: #160b0f;
    --rail-deep: #160b0f;
    --accent: #de91af;
}

:root[data-bs-theme="dark"][data-v3-brand="slate"] {
    --brand: #8c9db5;
    --brand-dark: #6f8098;
    --brand-darker: #c3cedd;
    --brand-soft: #232a35;
    --brand-softer: #1b2028;
    --brand-rgb: 140, 157, 181;
    --ink: #eaecee;
    --ink-muted: #a3a7ad;
    --line: #292d33;
    --surface: #181b20;
    --page: #101316;
    --rail: #0e1014;
    --rail-deep: #0e1014;
    --accent: #aab5c5;
}

/* ------------------------------------------------------------ the page ---- */
/* How the page sits behind the cards. These are the only tokens a reader can
   move without moving the hue: "default" is the brand's own tint, "soft"
   leans into it, "plain" takes it out entirely and "contrast" deepens the
   step between the page and the card on it. None of them can clash with the
   brand, because none of them invents a colour the brand has not already. */

:root[data-v3-page="soft"] {
    --page: var(--brand-softer);
    --line: var(--brand-soft);
}

:root[data-v3-page="plain"] {
    --surface: #ffffff;
    --page: #f4f5f6;
    --line: #e7e8ea;
}

:root[data-v3-page="contrast"] {
    --surface: #ffffff;
    --page: color-mix(in srgb, var(--brand) 9%, #eef0f1);
    --line: color-mix(in srgb, var(--brand) 14%, #dfe2e4);
}

:root[data-bs-theme="dark"][data-v3-page="soft"] {
    --page: var(--brand-softer);
    --surface: var(--brand-soft);
    --line: color-mix(in srgb, var(--brand) 22%, transparent);
}

:root[data-bs-theme="dark"][data-v3-page="plain"] {
    --surface: #17181a;
    --page: #0d0e0f;
    --line: #292b2e;
}

:root[data-bs-theme="dark"][data-v3-page="contrast"] {
    --surface: color-mix(in srgb, var(--brand) 10%, #1a1c1e);
    --page: #08090a;
    --line: color-mix(in srgb, var(--brand) 18%, #2b2e31);
}

/* ---------------------------------------------------------------- rail ---- */
/* The sidebar is the one large block of solid colour on the screen, so it is
   its own choice: the brand's deep rail, the brand itself, or a light rail
   for people who find a dark column heavy. All three come from the brand —
   there is no navy left to strand a rose site with a blue sidebar. */

:root[data-v3-rail="dark"] {
    --rail: var(--rail-deep);
}

:root[data-v3-rail="brand"] {
    --rail: var(--brand-dark);
}

:root[data-v3-rail="light"] {
    --rail: var(--surface);
    --rail-soft: color-mix(in srgb, var(--brand) 12%, transparent);
    --rail-text: var(--ink-muted);
}

:root[data-v3-rail="light"] .panel-sidebar {
    border-inline-end: 1px solid var(--line);
}

:root[data-v3-rail="light"] .panel-sidebar,
:root[data-v3-rail="light"] .panel-sidebar .brand-name,
:root[data-v3-rail="light"] .panel-rail-nav .nav-link {
    color: var(--ink);
}

:root[data-v3-rail="light"] .panel-rail-nav .nav-link.active {
    color: var(--on-brand);
}

:root[data-v3-rail="light"] .rail-mode-chip,
:root[data-v3-rail="light"] .panel-support {
    color: var(--ink);
}

/* `--accent` is the tint that reads on a dark rail; on a light one it is the
   brand itself, or the card's icon all but disappears into the surface. */
:root[data-v3-rail="light"] .panel-support i {
    color: var(--brand);
}

/* ---------------------------------------------------------- the picker ---- */
/* The panel itself is a surface like any other. It used to be Bootstrap's
   own offcanvas, which in the dark is a near-black with a blue cast — a navy
   sheet in front of a green page with pink buttons on it. */

/* Which side the panel comes in from is decided here, not by the offcanvas
   class in the template. The user panel loads Bootstrap's RTL build and the
   admin panel its theme's LTR one, and the two read `.offcanvas-start` as
   opposite physical sides — the same markup opened from the left in one
   panel and straight over the rail in the other. These rules pin it to the
   end of the line in both, and drive the slide with `translate` so nothing
   here depends on which build set `transform`. */
#personalize {
    position: fixed;
    top: 0;
    bottom: 0;
    left: auto;
    right: auto;
    inset-inline-end: 0;
    width: var(--bs-offcanvas-width);
    max-width: 100%;
    transform: none !important;
    translate: 100% 0;
    transition: translate 0.3s ease-in-out;
}

[dir="rtl"] #personalize {
    /* the end of the line is the left edge, so it hides off to the left */
    translate: -100% 0;
}

#personalize.showing,
#personalize.show:not(.hiding) {
    translate: 0 0;
}

@media (prefers-reduced-motion: reduce) {
    #personalize {
        transition: none;
    }
}

#personalize {
    --bs-offcanvas-bg: var(--surface);
    --bs-offcanvas-color: var(--ink);
    --bs-offcanvas-border-color: var(--line);
    --bs-offcanvas-width: 320px;
    color: var(--ink);
}

#personalize .offcanvas-header {
    border-color: var(--line) !important;
    align-items: flex-start;
}

/* The words take the free space and the close button is pushed to the far
   edge of the header. Bootstrap does that with `margin: -.5rem -.5rem -.5rem
   auto` on `.btn-close` — a *physical* auto on the right, which in a page
   that runs right to left is the same side the title is on, so the button
   came to rest against the text instead of the opposite corner. Written with
   logical properties it follows `dir` rather than which Bootstrap build the
   panel happens to load. */
#personalize .offcanvas-header > div {
    flex: 1 1 auto;
    min-width: 0;
}

#personalize .offcanvas-title {
    color: var(--ink);
}

#personalize .btn-close {
    filter: none;
    opacity: 0.6;
    flex-shrink: 0;
    margin: -0.5rem;
    margin-inline-start: auto;
}

[data-bs-theme="dark"] #personalize .btn-close {
    filter: invert(1) grayscale(100%) brightness(200%);
}

.personalize-group + .personalize-group {
    margin-top: 1.6rem;
}

.personalize-swatches {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
}

.personalize-swatch {
    width: 2.4rem;
    height: 2.4rem;
    border-radius: 50%;
    border: 2px solid transparent;
    box-shadow: 0 0 0 1px var(--line);
    cursor: pointer;
    padding: 0;
    position: relative;
    background-color: var(--surface);
}

.personalize-swatch.is-active {
    border-color: var(--brand);
    box-shadow: 0 0 0 2px var(--brand-soft);
}

.personalize-swatch.is-active::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3E%3Cpath d='M12.7 4.3a1 1 0 0 1 0 1.4l-5.5 5.5a1 1 0 0 1-1.4 0L3.3 8.7a1 1 0 1 1 1.4-1.4l1.8 1.8 4.8-4.8a1 1 0 0 1 1.4 0z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 1.1rem;
}

/* the brand swatches show the colour itself — the one place a literal value
   belongs, because the swatch *is* the value */
.personalize-swatch[data-value="green"] { background-color: #2f9e5e; }
.personalize-swatch[data-value="amber"] { background-color: #c07c22; }
.personalize-swatch[data-value="violet"] { background-color: #6d4bd6; }
.personalize-swatch[data-value="blue"] { background-color: #1f6fd0; }
.personalize-swatch[data-value="rose"] { background-color: #c2356b; }
.personalize-swatch[data-value="slate"] { background-color: #47566b; }

/* the page swatches preview the step between a card and the page behind it,
   in the brand that is active — so they change when the brand does */
.personalize-swatch[data-group="page"] {
    background-image: linear-gradient(135deg, var(--surface) 0 50%, var(--brand-softer) 50% 100%);
}

.personalize-swatch[data-value="soft"] {
    background-image: linear-gradient(135deg, var(--brand-softer) 0 50%, var(--brand-soft) 50% 100%);
}

.personalize-swatch[data-value="plain"] {
    background-image: linear-gradient(135deg, #ffffff 0 50%, #e7e8ea 50% 100%);
}

.personalize-swatch[data-value="contrast"] {
    background-image: linear-gradient(135deg, var(--surface) 0 50%, color-mix(in srgb, var(--brand) 20%, #d7dade) 50% 100%);
}

[data-bs-theme="dark"] .personalize-swatch[data-value="plain"] {
    background-image: linear-gradient(135deg, #17181a 0 50%, #0d0e0f 50% 100%);
}

.personalize-swatch[data-value="dark"] { background-color: var(--rail-deep); }
.personalize-swatch[data-value="brand"] { background-color: var(--brand-dark); }
.personalize-swatch[data-value="light"] {
    background-color: var(--surface);
    box-shadow: 0 0 0 1px var(--ink-muted);
}

/* a white tick disappears on a pale swatch */
.personalize-swatch[data-group="page"].is-active::after,
.personalize-swatch[data-value="light"].is-active::after {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23333'%3E%3Cpath d='M12.7 4.3a1 1 0 0 1 0 1.4l-5.5 5.5a1 1 0 0 1-1.4 0L3.3 8.7a1 1 0 1 1 1.4-1.4l1.8 1.8 4.8-4.8a1 1 0 0 1 1.4 0z'/%3E%3C/svg%3E");
}

[data-bs-theme="dark"] .personalize-swatch[data-group="page"].is-active::after,
[data-bs-theme="dark"] .personalize-swatch[data-value="light"].is-active::after {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3E%3Cpath d='M12.7 4.3a1 1 0 0 1 0 1.4l-5.5 5.5a1 1 0 0 1-1.4 0L3.3 8.7a1 1 0 1 1 1.4-1.4l1.8 1.8 4.8-4.8a1 1 0 0 1 1.4 0z'/%3E%3C/svg%3E");
}

.personalize-reset {
    margin-top: 1.8rem;
}

/* The button that opens the panel. Fixed to the *end* of the line — the left
   on a Persian page — so it never lands on the rail it is there to restyle,
   and on the opposite corner from the back-to-top button. */
.btn-personalize {
    position: fixed;
    inset-block-end: 1.5rem;
    inset-inline-end: 1.5rem;
    z-index: 1031;
    width: 44px;
    height: 44px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Flex centres the <i>, but the <i> is a 24px line box around a 16px
       glyph that bootstrap-icons then shifts by -.125em — so the icon sat
       low and left of the middle. Collapsing the line box to the glyph is
       what actually centres it. */
    line-height: 1;
    font-size: 1.1rem;
}

/* The <i> is a flex box of its own so the glyph is centred by layout rather
   than by a baseline: bootstrap-icons nudges `.bi::before` down by .125em,
   and a flex item ignores `vertical-align` entirely. */
.btn-personalize > i {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1em;
    height: 1em;
    line-height: 1;
}
