/* ==========================================================================
   Skin Plan - hand-written stylesheet.

   No CSS framework and no CDN on purpose: it keeps the Content-Security-Policy
   restrictive (style-src 'self') and the container works with no outbound
   internet access.
   ========================================================================== */

:root {
    /* ---- Kolory marki gabinetu -------------------------------------------
       Pięć kolorów z identyfikacji. Wszystkie pozostałe tokeny są z nich
       wyprowadzone (zmieszane z bielą albo przyciemnione), więc paleta ma
       jedno źródło prawdy. Zielenie prowadzą całą strukturę interfejsu;
       róże pojawiają się tylko tam, gdzie coś znaczą: we własnych
       wiadomościach i na znacznikach typu "wyświetlana" - patrz niżej.      */
    --brand-sage:   #859677;   /* szałwiowa zieleń */
    --brand-forest: #36493c;   /* ciemna zieleń */
    --brand-rose:   #d8959c;   /* przygaszony róż */
    --brand-blush:  #ead0d2;   /* jasny róż */
    --brand-paper:  #f4f3f2;   /* ciepła biel */

    /* ---- Tła ------------------------------------------------------------- */
    --bg: var(--brand-paper);
    --surface: #ffffff;
    --surface-alt: #f5f8f3;    /* szałwia ~6% na bieli */

    /* ---- Tekst (kontrast liczony na tle --bg) ---------------------------- */
    --ink: #253028;            /* przyciemniona zieleń marki - 12,7:1 */
    --ink-soft: #45564a;       /* 7,1:1 */
    --muted: #5d6f59;          /* 4,9:1 - próg AA dla drobnego tekstu */

    /* ---- Linie ----------------------------------------------------------- */
    --line: #e2e7dd;           /* szałwia ~22% na bieli */
    --line-strong: #cdd7c4;

    /* ---- Kolor akcji: ciemna zieleń marki -------------------------------- */
    --accent: var(--brand-forest);  /* biały tekst na tym: 9,7:1 */
    --accent-dark: #2a3a2f;         /* hover */
    --accent-soft: #e8eee3;         /* aktywna pigułka nawigacji */

    /* Szałwia i róż mają za mały kontrast, żeby nieść tekst (2,9:1 i 2,7:1),
       więc występują wyłącznie jako wypełnienia i obramowania. Do napisów
       służą ich przyciemnione warianty poniżej. */
    --sage: var(--brand-sage);
    --sage-deep: #5d6f59;      /* czytelna szałwia na napisy - 4,9:1 */
    --blush-soft: #f7ecec;     /* rozjaśniony róż marki */
    --blush-line: #ecd6d8;
    --rose-deep: #8a4a52;      /* czytelny róż na napisy - 5,7:1 na --blush-soft */

    /* ---- Kolory znaczeniowe ---------------------------------------------- */
    --ok: #3f6a4c;
    --ok-soft: #dfe8d6;
    --ok-line: #c6d4b8;
    --ok-ink: #2f4234;         /* 8,5:1 na --ok-soft */

    /* Bursztyn celowo odstaje od zielonej palety: tym kolorem oznaczamy
       notatki wewnętrzne, które nigdy nie mogą zostać pomylone z treścią
       widoczną dla klientki. */
    --warn: #8a6a2f;
    --warn-soft: #f7eedd;
    --warn-line: #e6d5ae;
    --warn-ink: #7c5518;

    --danger: #a4443f;
    --danger-soft: #f8e9e8;
    --danger-line: #e7c8c6;
    --danger-ink: #7d322e;

    /* Minimalistycznie: większe zaokrąglenia i cień rozmyty na tyle, że czyta się jako
       uniesienie karty nad tłem, a nie jako obrys - karty nie mają już ramek. */
    --radius: 16px;
    --radius-sm: 10px;
    --shadow: 0 1px 2px rgba(37, 48, 40, .04), 0 10px 30px -14px rgba(37, 48, 40, .16);
    --shadow-hover: 0 2px 4px rgba(37, 48, 40, .05), 0 18px 40px -16px rgba(37, 48, 40, .24);
    --font: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", Arial, sans-serif;
}


* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: var(--font);
    font-size: 16px;
    line-height: 1.6;
}

h1, h2, h3, h4 {
    margin: 0 0 .5rem;
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: -.01em;
}

/* Tytuł strony lżejszy i większy - spokojniej, a nadal wyraźnie najważniejszy. */
h1 { font-size: 1.85rem; font-weight: 500; letter-spacing: -.02em; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1.05rem; }

p { margin: 0 0 1rem; }

a {
    color: var(--accent-dark);
    text-decoration: none;
}

a:hover { text-decoration: underline; }

hr {
    border: 0;
    border-top: 1px solid var(--line);
    margin: 1.5rem 0;
}

code {
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-size: .9em;
    background: var(--surface-alt);
    border: 1px solid var(--line);
    border-radius: 4px;
    padding: .1em .35em;
}

/* ----- Shell ------------------------------------------------------------- */

.shell {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

.topbar {
    background: var(--surface);
    border-bottom: 1px solid var(--line);
}

.topbar-inner,
.container {
    width: 100%;
    max-width: 1080px;
    margin: 0 auto;
    padding: 0 1.25rem;
}

.topbar-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    min-height: 64px;
    flex-wrap: wrap;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--ink);
    letter-spacing: -.01em;
}

.brand:hover { text-decoration: none; }

/* Znak marki: ptak z logo NP Beauty. Plik jest przezroczysty i ma 3-krotną
   wysokość docelową, więc na ekranach o dużej gęstości pikseli zostaje ostry.
   Wysokość steruje rozmiarem, szerokość wynika z proporcji (9:16) - dzięki temu
   podmiana pliku na inny kadr nie zdeformuje znaku. */
.brand-mark {
    /* 38 px to najwięcej, co mieści się bez podniesienia belki - znak jest wąski
       (portretowy), więc dopiero na tej wysokości czyta się jako ptak, a nie kreska. */
    height: 38px;
    width: auto;
    flex: 0 0 auto;
}

.topbar-account {
    display: flex;
    align-items: center;
    gap: .85rem;
    font-size: .9rem;
    color: var(--muted);
    flex-wrap: wrap;
}

.nav-row {
    background: var(--surface);
    border-bottom: 1px solid var(--line);
}

.nav-pills {
    display: flex;
    gap: .35rem;
    overflow-x: auto;
    padding: .5rem 0 .6rem;
}

.nav-pill {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .4rem .8rem;
    border-radius: 999px;
    font-size: .9rem;
    color: var(--ink-soft);
    white-space: nowrap;
}

.nav-pill:hover {
    background: var(--surface-alt);
    text-decoration: none;
}

.nav-pill.active {
    background: var(--accent-soft);
    color: var(--accent-dark);
    font-weight: 600;
}

main { flex: 1 0 auto; padding: 2rem 0 3rem; }

.site-footer {
    border-top: 1px solid var(--line);
    background: var(--surface);
    padding: 1.25rem 0;
    font-size: .85rem;
    color: var(--muted);
}

.site-footer .container {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    justify-content: space-between;
}

.footer-links { display: flex; gap: 1rem; flex-wrap: wrap; }

/* ----- Page heading ------------------------------------------------------ */

.page-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.75rem;
}

.page-head p { margin: 0; color: var(--muted); }

.eyebrow {
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--sage-deep);
    font-weight: 600;
    margin-bottom: .25rem;
}

/* ----- Cards ------------------------------------------------------------- */

.card {
    background: var(--surface);
    border: 0;
    border-radius: var(--radius);
    padding: 1.6rem;
    box-shadow: var(--shadow);
}

.card + .card { margin-top: 1.25rem; }

.card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.card-head h2, .card-head h3 { margin: 0; }

.grid {
    display: grid;
    gap: 1.1rem;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

/* Dashboard tiles. Bez ramki; strzałka w rogu mówi "to się otwiera" bez słowa. */
.tile {
    position: relative;
    display: block;
    background: var(--surface);
    border-radius: var(--radius);
    padding: 1.4rem 3rem 1.4rem 1.4rem;
    color: var(--ink);
    box-shadow: var(--shadow);
    transition: box-shadow .2s ease, transform .2s ease;
}

.tile::after {
    content: "→";
    position: absolute;
    right: 1.3rem;
    bottom: 1.25rem;
    color: var(--sage);
    font-size: 1.1rem;
    transition: transform .2s ease, color .2s ease;
}

.tile:hover {
    text-decoration: none;
    box-shadow: var(--shadow-hover);
    transform: translateY(-2px);
}

.tile:hover::after { transform: translateX(3px); color: var(--accent); }

.tile-title {
    font-weight: 600;
    margin-bottom: .2rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
}

.tile-sub { color: var(--muted); font-size: .9rem; }

/* ----- Buttons ----------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    padding: .6rem 1.15rem;
    border-radius: 999px;
    border: 1px solid transparent;
    background: var(--accent);
    color: #fff;
    font-family: inherit;
    font-size: .92rem;
    font-weight: 500;
    cursor: pointer;
    text-decoration: none;
}

.btn:hover { background: var(--accent-dark); text-decoration: none; color: #fff; }
.btn:disabled { opacity: .55; cursor: not-allowed; }

.btn-secondary {
    background: var(--surface);
    border-color: var(--line-strong);
    color: var(--ink);
}

.btn-secondary:hover { background: var(--surface-alt); color: var(--ink); }

.btn-danger { background: var(--danger); }
.btn-danger:hover { background: #8b3934; }  /* --danger przyciemniony */

.btn-sm { padding: .35rem .7rem; font-size: .85rem; }

.btn-row { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }

/* ----- Forms ------------------------------------------------------------- */

.field { margin-bottom: 1rem; }

.field label {
    display: block;
    font-size: .88rem;
    font-weight: 500;
    color: var(--ink-soft);
    margin-bottom: .3rem;
}

.field-hint { font-size: .82rem; color: var(--muted); margin-top: .25rem; }

/* input:not([type]) because <InputText> renders no type attribute at all. */
input:not([type]), input[type=text], input[type=email], input[type=tel], input[type=date],
input[type=number], input[type=search], select, textarea {
    width: 100%;
    padding: .55rem .7rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--ink);
    font-family: inherit;
    font-size: .95rem;
}

/* Pole w fokusie: zielona poświata zamiast twardej ramki. Obrys zostaje (2 px), bo sama
   poświata jest za słaba dla osób, które nawigują klawiaturą. */
input:focus, select:focus, textarea:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    box-shadow: 0 0 0 5px var(--accent-soft);
}

.btn:focus-visible, a:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Blazor's FocusOnNavigate moves focus to the page heading after every navigation so
   screen readers announce it. Chrome reports that programmatic focus as :focus-visible,
   which would draw a ring around every page title. The heading carries tabindex="-1" and
   is therefore never reachable with Tab, so suppressing the ring costs no keyboard
   affordance. */
h1[tabindex="-1"]:focus { outline: none; }

textarea { resize: vertical; min-height: 8rem; line-height: 1.55; }

textarea.editor {
    min-height: 22rem;
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-size: .9rem;
}

/* ----- Edytor treści (rich-editor.js) --------------------------------------- */

/* Reguły, które TipTap normalnie wstrzykuje sam przez <style> - wyłączone, bo CSP to
   style-src 'self'. Bez white-space: pre-wrap spacje i nowe linie znikałyby w trakcie
   pisania. */
.ProseMirror { position: relative; word-wrap: break-word; white-space: pre-wrap; white-space: break-spaces; font-variant-ligatures: none; outline: none; }
.ProseMirror [contenteditable="false"] { white-space: normal; }
.ProseMirror-selectednode { outline: 2px solid var(--accent); outline-offset: 1px; }
.ProseMirror-gapcursor { display: none; pointer-events: none; position: absolute; }
.ProseMirror-focused .ProseMirror-gapcursor { display: block; }
.ProseMirror p.is-editor-empty:first-child::before {
    content: attr(data-placeholder);
    float: left;
    height: 0;
    color: var(--muted);
    pointer-events: none;
}

.re-host {
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
}

.re-host:focus-within { border-color: var(--accent); box-shadow: 0 0 0 5px var(--accent-soft); }

/* Pasek przyklejony do góry pola: na telefonie, gdy klawiatura zajmuje pół ekranu, nadal
   jest widoczny nad tekstem, który się pisze. */
.re-toolbar {
    position: sticky;
    top: 0;
    z-index: 4;
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    padding: .45rem;
    background: var(--surface-alt);
    border-bottom: 1px solid var(--line);
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

.re-tool {
    min-height: 2.25rem;
    padding: .3rem .75rem;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    background: var(--surface);
    color: var(--ink);
    font: inherit;
    font-size: .85rem;
    cursor: pointer;
    touch-action: manipulation;
}

.re-tool:hover { border-color: var(--accent); }
.re-tool.is-active { background: var(--accent); border-color: var(--accent); color: #fff; }
.re-tool.re-bold { font-weight: 700; min-width: 2.25rem; }

.re-content {
    min-height: 18rem;
    padding: .9rem 1rem;
    line-height: 1.6;
}

.re-content.re-compact { min-height: 10rem; }

.re-content h2 {
    font-size: 1.05rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--sage-deep);
    margin: 1rem 0 .4rem;
}

.re-content h3 { font-size: 1rem; margin: .8rem 0 .3rem; }
.re-content h2:first-child, .re-content h3:first-child { margin-top: 0; }
.re-content p { margin: 0 0 .5rem; }
.re-content ul, .re-content ol { margin: 0 0 .6rem; padding-left: 1.4rem; }
.re-content li > p { margin: 0 0 .2rem; }

/* Kosmetyk w treści - ten sam kafelek co w gotowym planie, tylko mniejszy. */
.re-product {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .1rem .5rem .1rem .15rem;
    margin: 0 .1rem;
    border-radius: var(--radius-sm);
    background: var(--accent-soft);
    border: 1px solid var(--line-strong);
    color: var(--accent-dark);
    font-weight: 500;
    vertical-align: middle;
    user-select: none;
}

/* Zabieg w treści wizyty - kafelek jak kosmetyk, z przerywaną ramką jak blok propozycji. */
.re-treatment { border-style: dashed; }

.re-product img {
    width: 26px;
    height: 26px;
    object-fit: contain;
    border-radius: 6px;
    background: #fff;
}

/* Menu pod kursorem dla "@" i "/". */
.re-menu {
    position: absolute;
    z-index: 50;
    min-width: 14rem;
    max-width: min(22rem, calc(100vw - 16px));
    max-height: 18rem;
    overflow-y: auto;
    padding: .3rem;
    background: var(--surface);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-hover);
    border: 1px solid var(--line);
}

.re-menu-item {
    display: flex;
    align-items: center;
    gap: .5rem;
    width: 100%;
    min-height: 2.5rem;
    padding: .35rem .55rem;
    border: 0;
    border-radius: 8px;
    background: none;
    color: var(--ink);
    font: inherit;
    font-size: .92rem;
    text-align: left;
    cursor: pointer;
}

.re-menu-item small { margin-left: auto; color: var(--muted); font-size: .78rem; }
.re-menu-item img { width: 28px; height: 28px; object-fit: contain; border-radius: 6px; background: #fff; flex: 0 0 auto; }
.re-menu-item.is-active, .re-menu-item:hover { background: var(--accent-soft); }
.re-menu-empty { padding: .5rem .6rem; color: var(--muted); font-size: .9rem; }

kbd {
    font-family: inherit;
    font-size: .85em;
    padding: .05em .4em;
    border: 1px solid var(--line-strong);
    border-bottom-width: 2px;
    border-radius: 5px;
    background: var(--surface);
}

/* Wybór jednej z kilku opcji (rodzaj szablonu). */
.choice-row { border: 0; padding: 0; margin: 0 0 1rem; }
.choice-row legend { font-size: .88rem; font-weight: 500; color: var(--ink-soft); margin-bottom: .4rem; padding: 0; }
.choice-row .choice {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    margin: 0 1.25rem .35rem 0;
    font-size: .95rem;
    cursor: pointer;
}

/* Zalecenia w formularzu wizyty - pole w środku dłuższego formularza, więc niższe. */
textarea.editor.editor-compact { min-height: 12rem; }

.checkbox-row {
    display: flex;
    align-items: flex-start;
    gap: .55rem;
    margin-bottom: 1rem;
}

.checkbox-row input { margin-top: .35rem; }
.checkbox-row label { margin: 0; font-weight: 400; color: var(--ink); }
.checkbox-row label .field-hint { display: block; margin-top: .15rem; }

.form-grid {
    display: grid;
    gap: 0 1rem;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

.validation-message, .validation-errors {
    color: var(--danger);
    font-size: .85rem;
}

.validation-errors ul { margin: 0; padding-left: 1.1rem; }

/* ----- Alerts ------------------------------------------------------------ */

.alert {
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: .8rem 1rem;
    margin-bottom: 1.25rem;
    font-size: .92rem;
}

.alert-error { background: var(--danger-soft); border-color: var(--danger-line); color: var(--danger-ink); }
.alert-ok { background: var(--ok-soft); border-color: var(--ok-line); color: var(--ok-ink); }
.alert-info { background: var(--accent-soft); border-color: var(--line-strong); color: var(--accent-dark); }
.alert-warn { background: var(--warn-soft); border-color: var(--warn-line); color: var(--warn-ink); }

/* ----- Badges ------------------------------------------------------------ */

.badge {
    display: inline-block;
    white-space: nowrap;
    padding: .12rem .5rem;
    border-radius: 999px;
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .01em;
    background: var(--surface-alt);
    border: 1px solid var(--line);
    color: var(--muted);
    vertical-align: middle;
}

.badge:not(:first-child) { margin-left: .3rem; }

.badge-active { background: var(--ok-soft); border-color: var(--ok-line); color: var(--ok-ink); }

/* Róż marki 1/2: znaczniki "wyświetlana" i "to Ty". */
.badge-accent { background: var(--blush-soft); border-color: var(--blush-line); color: var(--rose-deep); }

.badge-internal { background: var(--warn-soft); border-color: var(--warn-line); color: var(--warn-ink); }
.badge-count { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ----- Lists and tables -------------------------------------------------- */

.list { list-style: none; margin: 0; padding: 0; }

.list > li {
    padding: .85rem 0;
    border-top: 1px solid var(--line);
}

.list > li:first-child { border-top: 0; }

.row-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    color: var(--ink);
    flex-wrap: wrap;
}

.row-link:hover { text-decoration: none; color: var(--accent-dark); }
.row-main { min-width: 0; }
.row-title { display: block; font-weight: 500; }
.row-sub { display: block; font-size: .86rem; color: var(--muted); }
.row-side { font-size: .86rem; color: var(--muted); display: flex; gap: .5rem; align-items: center; }

.table-wrap { overflow-x: auto; }

table {
    width: 100%;
    border-collapse: collapse;
    font-size: .92rem;
}

th, td {
    text-align: left;
    padding: .65rem .75rem;
    border-bottom: 1px solid var(--line);
    vertical-align: top;
}

th {
    font-size: .8rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--muted);
    font-weight: 600;
}

tbody tr:last-child td { border-bottom: 0; }

.dl { margin: 0; }
.dl div { display: flex; gap: .75rem; padding: .5rem 0; border-top: 1px solid var(--line); }
.dl div:first-child { border-top: 0; }
.dl dt { flex: 0 0 40%; color: var(--muted); font-size: .9rem; }
.dl dd { margin: 0; flex: 1 1 auto; }

.empty {
    text-align: center;
    padding: 2rem 1rem;
    color: var(--muted);
    font-size: .93rem;
}

/* ----- Rendered plan / note content -------------------------------------- */

.prose { line-height: 1.7; }
.prose > :first-child { margin-top: 0; }
.prose h1, .prose h2, .prose h3 { margin: 1.6rem 0 .6rem; }
.prose h2 {
    font-size: 1rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--sage-deep);
    padding-bottom: .35rem;
    border-bottom: 1px solid var(--line);
}
.prose h3 { font-size: .98rem; }
.prose ol, .prose ul { padding-left: 1.3rem; margin: 0 0 1rem; }
.prose li { margin-bottom: .35rem; }
.prose strong { color: var(--ink); }
.prose blockquote {
    margin: 0 0 1rem;
    padding: .5rem 0 .5rem 1rem;
    border-left: 3px solid var(--sage);
    color: var(--ink-soft);
}
.prose table { margin-bottom: 1rem; }
.text-preserve { white-space: pre-wrap; }

/* ----- Version history --------------------------------------------------- */

.versions { list-style: none; margin: 0; padding: 0; }

.versions li {
    display: flex;
    align-items: baseline;
    gap: .75rem;
    padding: .6rem 0;
    border-top: 1px solid var(--line);
    flex-wrap: wrap;
}

.versions li:first-child { border-top: 0; }
.version-no { font-weight: 600; min-width: 5.5rem; }
.version-date { color: var(--muted); font-size: .88rem; }

/* ----- Messages ---------------------------------------------------------- */

.thread {
    display: flex;
    flex-direction: column;
    gap: .75rem;
    max-height: 60vh;
    overflow-y: auto;
    padding: .25rem;
}

.msg { max-width: 78%; }
.msg-mine { align-self: flex-end; }

.msg-bubble {
    padding: .6rem .85rem;
    border-radius: var(--radius);
    background: var(--surface-alt);
    border: 1px solid var(--line);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* Róż marki 2/2: własne wiadomości. Wiadomości drugiej strony zostają na
   szałwiowym tle, więc rozmowa czyta się bez patrzenia na podpisy. */
.msg-mine .msg-bubble {
    background: var(--blush-soft);
    border-color: var(--blush-line);
}

.msg-meta {
    font-size: .76rem;
    color: var(--muted);
    margin-top: .2rem;
    padding: 0 .2rem;
}

.msg-mine .msg-meta { text-align: right; }

.composer { display: flex; flex-direction: column; gap: .6rem; margin-top: 1.25rem; }
.composer textarea { min-height: 5.5rem; }
.composer-row { display: flex; justify-content: space-between; align-items: center; gap: .75rem; flex-wrap: wrap; }

.poll-note { font-size: .8rem; color: var(--muted); }

/* ----- Auth / marketing -------------------------------------------------- */

.narrow { max-width: 640px; margin: 0 auto; }
.centered { text-align: center; }

.hero {
    text-align: center;
    padding: 2.5rem 0 1.5rem;
}

.hero h1 { font-size: 2.1rem; }
.hero p { color: var(--ink-soft); max-width: 46ch; margin: 0 auto 1.5rem; }

/* One button shape for every external provider. Renamed from .google-btn when Facebook and
   Microsoft joined - the layout was never Google-specific. */
.sso-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .6rem;
    width: 100%;
    padding: .7rem 1rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--ink);
    font-size: .98rem;
    font-weight: 500;
    cursor: pointer;
}

.sso-btn:hover { background: var(--surface-alt); text-decoration: none; color: var(--ink); }

/* Only the initial badge is tinted, so the buttons stay a quiet row in the salon's palette
   rather than three competing brand colours. */
.sso-btn > span[aria-hidden] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    background: var(--surface-alt);
    font-weight: 700;
    font-size: .85rem;
}

.sso-google > span[aria-hidden] { background: #f4f3f2; color: #36493c; }
.sso-facebook > span[aria-hidden] { background: #e7ecf5; color: #2c4372; }
.sso-microsoft > span[aria-hidden] { background: #eef1ee; color: #36493c; }

.dev-panel {
    margin-top: 1.5rem;
    border: 1px dashed var(--warn-line);
    background: var(--warn-soft);
    border-radius: var(--radius);
    padding: 1.1rem 1.25rem;
}

.dev-panel h3 { margin-top: 0; font-size: .95rem; color: var(--warn-ink); }
.dev-list { list-style: none; margin: .75rem 0 0; padding: 0; }
.dev-list li { padding: .35rem 0; border-top: 1px solid var(--warn-line); display: flex; justify-content: space-between; align-items: center; gap: .75rem; flex-wrap: wrap; }
.dev-list li:first-child { border-top: 0; }
.dev-role { font-size: .78rem; color: var(--warn-ink); }

/* ----- Utilities --------------------------------------------------------- */

.muted { color: var(--muted); }
.small { font-size: .86rem; }
.stack > * + * { margin-top: 1rem; }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
.spread { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; }
.nowrap { white-space: nowrap; }
.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ----- Blazor's own error banner ----------------------------------------- */

#blazor-error-ui {
    display: none;
    position: fixed;
    inset: auto 0 0 0;
    z-index: 1000;
    background: var(--warn-soft);
    border-top: 1px solid var(--warn-line);
    color: var(--warn-ink);
    padding: .8rem 1.25rem;
    font-size: .9rem;
    text-align: center;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    float: right;
    font-weight: 700;
    padding: 0 .35rem;
}

.blazor-error-boundary {
    background: var(--danger-soft);
    border: 1px solid var(--danger-line);
    border-radius: var(--radius-sm);
    padding: 1rem;
    color: var(--danger-ink);
}

/* ----- Responsive -------------------------------------------------------- */

@media (max-width: 720px) {
    body { font-size: 15px; }
    h1 { font-size: 1.4rem; }
    .hero h1 { font-size: 1.7rem; }
    main { padding: 1.25rem 0 2rem; }
    .card { padding: 1.1rem; }
    .topbar-inner { min-height: 56px; padding-top: .5rem; padding-bottom: .5rem; }
    .msg { max-width: 90%; }
    .dl div { flex-direction: column; gap: .1rem; }
    .dl dt { flex: none; }
    .thread { max-height: none; }
}

@media (prefers-reduced-motion: reduce) {
    * { transition: none !important; }
}

/* ----- Sub navigation (staff client tabs) -------------------------------- */

.subnav {
    border-bottom: 1px solid var(--line);
    margin: -.5rem 0 1.5rem;
}

.subnav .nav-pills { padding: 0 0 .6rem; }

/* ----- "albo" separator between sign-in methods -------------------------- */

.or-divider {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin: 1.5rem 0;
    color: var(--muted);
    font-size: .82rem;
    text-transform: uppercase;
    letter-spacing: .08em;
}

.or-divider::before,
.or-divider::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: var(--line);
}

/* ----- Date field split into day / month / year ------------------------- */

.date-parts {
    display: grid;
    /* The month column has to hold "październik", so it gets the slack. */
    grid-template-columns: 6rem minmax(0, 1fr) 6.5rem;
    gap: .5rem;
    max-width: 26rem;
}

.date-parts select { min-width: 0; }

/* A date needs the whole row of a two-column form grid to stay readable. */
.field-wide { grid-column: 1 / -1; }

@media (max-width: 460px) {
    .date-parts { grid-template-columns: 1fr 1fr; }
    .date-parts select:nth-child(2) { grid-column: 1 / -1; order: -1; }
}

/* ----- Cosmetics catalogue ----------------------------------------------- */

.product-thumb {
    width: 64px;
    height: 64px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    border: 1px solid var(--line);
    background: var(--surface-alt);
    flex: 0 0 auto;
}

.product-thumb-sm { width: 44px; height: 44px; }

/* Placeholder square so rows with and without a photo line up. */
.product-thumb-empty {
    display: inline-block;
    background: var(--surface-alt);
}

.product-row { display: flex; align-items: center; gap: .75rem; }

.photo-row { display: flex; align-items: center; gap: .75rem; margin-bottom: .6rem; }

.product-photo {
    display: block;
    max-width: 260px;
    width: 100%;
    height: auto;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    margin-bottom: 1.25rem;
}

/* A product reference inside a rendered plan. The renderer emits an ordinary Markdown link,
   so this is the only thing that makes it look like something to tap. */
.prose a[href^="/produkty/"],
.prose a[href^="/zabiegi/"] {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    max-width: 100%;
    vertical-align: middle;
    margin: .15rem 0;
    padding: .25rem .6rem .25rem .25rem;
    border-radius: var(--radius-sm);
    background: var(--accent-soft);
    border: 1px solid var(--line-strong);
    color: var(--accent-dark);
    text-decoration: none;
    font-weight: 500;
}

.prose a[href^="/produkty/"]:hover,
.prose a[href^="/zabiegi/"]:hover {
    background: var(--accent-soft);
    border-color: var(--sage);
    text-decoration: none;
}

/* ----- Pickers under the plan editor ------------------------------------- */

.picker {
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface-alt);
    padding: .9rem 1rem;
    margin-bottom: 1rem;
}

.picker .card-head { margin-bottom: .6rem; }
/* Zwinięta lista kosmetyków: sam nagłówek, bez pustego odstępu pod nim. */
.picker .card-head:last-child { margin-bottom: 0; }
.picker h3 { margin: 0; font-size: .95rem; }

.picker-chips {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin: .6rem 0 .5rem;
}

.picker-chip {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .25rem .6rem .25rem .3rem;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    background: var(--surface);
    color: var(--ink);
    font-family: inherit;
    font-size: .85rem;
    cursor: pointer;
}

.picker-chip:hover { border-color: var(--accent); background: var(--accent-soft); }

.picker-chip img {
    width: 24px;
    height: 24px;
    object-fit: cover;
    border-radius: 50%;
    flex: 0 0 auto;
}

.picker-chip > span { padding-left: .15rem; }

/* ----- Filtry katalogu, marki i kategorie --------------------------------- */

.filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    align-items: center;
}

.filter-bar input[type="search"] { flex: 1 1 14rem; width: auto; }
.filter-bar select { flex: 0 1 12rem; width: auto; }

.inline-form {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    align-items: center;
    margin-bottom: .8rem;
}

.inline-form input { flex: 1 1 14rem; width: auto; }

.category-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
}

.category-row .inline-form { flex: 1 1 100%; margin-bottom: 0; }

/* ----- Wizyty i zalecenia po zabiegu ---------------------------------------- */

/* Przycisk zaleceń: ciemna zieleń marki (--brand-forest), na której biały tekst ma 9,7:1.
   Zwykły .btn ma ten sam kolor, więc tu wyróżnia go kształt - pełna pigułka ze strzałką -
   a na stronie startowej rozmiar. */
.btn-recommendation {
    gap: .55rem;
    padding: .7rem 1.3rem;
    font-weight: 600;
}

.btn-recommendation::after { content: "→"; transition: transform .2s ease; }
.btn-recommendation:hover::after { transform: translateX(3px); }

/* Wersja na stronę startową: na całą szerokość, duża - do trafienia kciukiem - z datą
   wizyty w drugiej linii. */
.btn-hero {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    padding: 1.15rem 1.5rem;
    margin-bottom: 1.5rem;
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    text-align: left;
}

.btn-hero:hover { box-shadow: var(--shadow-hover); }

.btn-hero-label { display: flex; flex-direction: column; gap: .1rem; }
.btn-hero-title { font-size: 1.12rem; font-weight: 600; }
.btn-hero-sub { font-size: .88rem; font-weight: 400; opacity: .85; }
.btn-hero::after { font-size: 1.3rem; }

/* Wizyty klientki: każda wizyta to osobna karta. */
.visit-list { display: flex; flex-direction: column; gap: 1.25rem; }
.visit-list .card + .card { margin-top: 0; }

.visit-card { display: flex; flex-direction: column; gap: .75rem; }

/* Panel kosmetologa: data po lewej, "Edytuj / Usuń" po prawej; na wąskim ekranie przyciski
   schodzą pod datę. */
.visit-card-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
    flex-wrap: wrap;
}

.visit-card-head .row-sub { margin-top: -.15rem; }
.visit-card .recommendation-box { margin-bottom: 0; }

.visits-toolbar { margin-bottom: 1.25rem; }
.visit-card .note-photos { margin-top: 0; }
.visit-card-actions { margin-top: .25rem; }

.visit-date {
    font-size: 1.2rem;
    font-weight: 500;
    letter-spacing: -.01em;
    padding-bottom: .6rem;
    margin-bottom: .1rem;
    position: relative;
}

/* Krótka kreska pod datą - jedyny "ozdobnik" karty. */
.visit-date::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: 2.25rem;
    height: 2px;
    border-radius: 2px;
    background: var(--sage);
}

.list > li.visit { display: flex; flex-direction: column; gap: .5rem; }

/* Blok zaleceń (panel kosmetologa). Szałwia zamiast dawnej czerwieni - zalecenia są
   zielone w całym portalu; czerwony zostaje dla usuwania i błędów. */
.recommendation-box {
    border-left: 3px solid var(--sage);
    background: var(--surface-alt);
    border-radius: var(--radius-sm);
    padding: .85rem 1.1rem;
    margin: .25rem 0 1rem;
}

.recommendation-title { font-weight: 600; color: var(--accent); margin-bottom: .35rem; }

/* Strona zaleceń czytana na telefonie, zaraz po zabiegu - większa czcionka. */
.recommendation-sheet { font-size: 1.08rem; line-height: 1.65; }

.link-button {
    background: none;
    border: 0;
    padding: 0;
    color: var(--accent);
    text-decoration: underline;
    font: inherit;
    cursor: pointer;
}

/* Hurtowa zmiana cen. */
.list > li.price-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .6rem .5rem;
}

.price-row-changed { background: var(--accent-soft); }
.price-row-invalid { background: var(--warn-soft); }
.price-row-invalid .row-sub { color: var(--warn-ink); font-weight: 600; }

.price-field {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    flex: 0 0 auto;
}

.price-field input { width: 7rem; text-align: right; }

/* Przycisk zapisu zostaje na dole ekranu, żeby przy długiej liście nie trzeba było do niego
   przewijać. */
.save-bar {
    position: sticky;
    bottom: 0;
    z-index: 5;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem;
    padding: .75rem 0;
    background: var(--bg);
    border-top: 1px solid var(--line);
    margin-bottom: 1rem;
}

.product-size { color: var(--muted); font-weight: 500; }

/* Podgląd miniatury do planu w edytorze - w tym samym kształcie, w jakim zobaczy ją
   klientka, na szachownicy, żeby było widać przezroczyste tło. */
.product-thumb-free {
    height: 48px;
    width: auto;
    max-width: 96px;
    object-fit: contain;
    padding: 4px;
    border: 1px dashed var(--line-strong);
    border-radius: var(--radius-sm);
    background: repeating-conic-gradient(#eee 0 25%, #fff 0 50%) 0 0 / 12px 12px;
}

/* Podgląd logo na liście marek i w edytorze: pole o stałym rozmiarze, logo w środku. */
.brand-logo-tile {
    display: inline-block;
    width: 88px;
    height: 44px;
    object-fit: contain;
    border-radius: var(--radius-sm);
    border: 1px solid var(--line);
    background: #fff;
    flex: 0 0 auto;
}

.product-facts {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem;
    margin-bottom: 1rem;
}

.product-facts .badge { margin-left: 0; }

.brand-logo {
    height: 40px;
    width: auto;
    max-width: 160px;
    object-fit: contain;
}

.product-price {
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--accent-dark);
}

/* ----- Zdjęcia przy notatkach --------------------------------------------- */

.note-photos { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: .7rem; }

.note-photo { display: flex; flex-direction: column; gap: .35rem; align-items: flex-start; }

.note-photo-link { display: block; line-height: 0; border-radius: var(--radius-sm); }

/* Świadomie nie .product-thumb: zmiana miniatury w katalogu nie ma prawa
   przeskalować zdjęcia skóry klientki ani odwrotnie. */
.note-thumb {
    width: 96px;
    height: 96px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    border: 1px solid var(--line);
    background: var(--surface-alt);
}

/* Powiększenie bez JavaScriptu, na :target. Dzięki temu działa również na
   stronach klientki, które są renderowane statycznie i nie mają obwodu,
   i nie wymaga niczego od script-src. Sam link musi jednak nieść ścieżkę
   i data-enhance-nav="false" - powody w NoteList.razor. */
.lightbox {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 900;              /* pod #blazor-error-ui (1000), żeby błąd pozostał widoczny */
    padding: 1.5rem;
    align-items: center;
    justify-content: center;
    background: rgba(37, 48, 40, .85);
}

.lightbox:target { display: flex; }

.lightbox-backdrop { position: absolute; inset: 0; cursor: zoom-out; }

.lightbox-image {
    position: relative;
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    background: var(--surface);
}

.lightbox-close {
    position: absolute;
    top: 1rem;
    right: 1rem;
    padding: .35rem .8rem;
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--ink);
    text-decoration: none;
    font-size: .9rem;
}

@media (max-width: 460px) {
    .note-thumb { width: 78px; height: 78px; }
}

/* ----- Utracone połączenie (obwód Blazora) -------------------------------- */

/* Blazor sam nie stylizuje tej nakładki, jeśli dostarczymy jej znacznik - tylko
   przełącza klasy. Dzięki temu nie wstrzykuje własnego bloku <style>, który
   blokowałaby CSP (style-src 'self'), i awaria obwodu jest w końcu widoczna
   zamiast wyglądać na zawieszoną stronę. */

#components-reconnect-modal { display: none; }

#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected {
    display: flex;
    position: fixed;
    inset: 0;
    z-index: 1100;                 /* nad nakładką zdjęcia (900) i błędem (1000) */
    align-items: flex-start;
    justify-content: center;
    padding: 1.25rem;
    background: rgba(37, 48, 40, .45);
}

#components-reconnect-modal .reconnect-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: .9rem 1.1rem;
    max-width: 30rem;
    font-size: .95rem;
    color: var(--ink);
}

#components-reconnect-modal .reconnect-card p { margin: 0; }

/* Domyślnie żaden komunikat; klasa stanu wybiera właściwy. */
#components-reconnect-modal .reconnect-lost,
#components-reconnect-modal .reconnect-failed,
#components-reconnect-modal .reconnect-rejected { display: none; }

#components-reconnect-modal.components-reconnect-show    .reconnect-lost     { display: block; }
#components-reconnect-modal.components-reconnect-failed   .reconnect-failed   { display: block; }
#components-reconnect-modal.components-reconnect-rejected .reconnect-rejected { display: block; }

#components-reconnect-modal .reconnect-reload { font-weight: 600; }

/* Obrazek kosmetyku w treści planu. Renderer wstawia obraz Markdowna przed nazwą tylko
   wtedy, gdy katalog ma miniaturę albo zdjęcie - więc nie ma tu przypadku "brakujący
   plik". 48 px wysokości, bo na telefonie mniejszego opakowania nie da się rozpoznać. */

/* Miniatura do planu: dowolny kształt i zwykle przezroczyste tło (wycięte opakowanie),
   więc bez ramki. Szerokość z proporcji, z górną granicą, żeby szeroki słoik nie wypchnął
   nazwy. */
.prose a[href^="/produkty/"] img[src$="/miniatura"] {
    height: 48px;
    width: auto;
    max-width: 96px;
    object-fit: contain;
    flex: 0 0 auto;
}

/* Zdjęcie produktu jako zapas, gdy miniatury nie wgrano: kwadrat w ramce, contain, żeby
   wysoka butelka nie została ucięta. */
.prose a[href^="/produkty/"] img[src$="/zdjecie"],
.prose a[href^="/zabiegi/"] img[src$="/zdjecie"] {
    width: 48px;
    height: 48px;
    object-fit: contain;
    border-radius: var(--radius-sm);
    border: 1px solid var(--line-strong);
    background: #fff;
    flex: 0 0 auto;
}

/* ----- Wydruk planu ------------------------------------------------------- */

/* Widoczne wyłącznie na papierze. */
.print-only { display: none; }

/* Papier firmowy nad planem: znak marki i nazwa gabinetu. Obrazek, nie tło - przeglądarki
   domyślnie nie drukują teł, a <img> drukują zawsze. */
.print-letterhead {
    align-items: center;
    gap: .6rem;
    margin: 0 0 1rem;
    padding-bottom: .6rem;
    border-bottom: 1px solid #999;
}

.print-letterhead .print-logo { height: 30px; width: auto; }

.print-letterhead strong { display: block; font-size: 1rem; }

.print-letterhead span { font-size: .85rem; color: #333; }

@media print {
    /* Interfejs nie jedzie na papier: belka, nawigacja, stopka, przyciski i wszystko,
       co służy do klikania. Zostaje sam plan. */
    .topbar,
    .nav-row,
    .site-footer,
    .btn-row,
    .screen-only,
    #blazor-error-ui,
    #components-reconnect-modal,
    .lightbox { display: none !important; }

    .print-only { display: block; }
    .print-letterhead { display: flex; }

    /* Puste kartki na końcu wydruku.
       Powłoka strony ma min-height: 100vh i rozpycha się przez main { flex: 1 0 auto },
       żeby stopka trzymała się dołu ekranu. W druku to nie ma sensu, a na telefonie bywa
       wręcz szkodliwe: silniki druku (zwłaszcza iOS) liczą vh od wysokości ekranu, nie
       kartki, więc wymuszona wysokość wystaje za pierwszą stronę i drukarka dokłada
       pustą. Headless Chromium tego nie odtwarza - dlatego to zostało przeoczone. */
    html, body { height: auto; margin: 0; padding: 0; }

    .shell {
        min-height: 0;
        display: block;
    }

    main { flex: none; }

    /* Margines ostatniego akapitu potrafi sam przelać się na kolejną stronę. */
    .prose > *:last-child,
    .card > *:last-child { margin-bottom: 0; }

    /* Czcionka drukarska i pełna szerokość arkusza - cienie i ramki kart tylko zużywają
       toner. */
    html, body {
        background: #fff;
        color: #000;
        font-size: 11pt;
    }

    .shell, .container, .narrow { max-width: none; padding: 0; margin: 0; }

    .card, .plan-sheet {
        border: 0;
        box-shadow: none;
        padding: 0;
        margin: 0;
        background: transparent;
    }

    main { padding: 0 !important; }

    /* Odnośnik do kosmetyku na papierze jest tekstem, nie przyciskiem - adres i tak
       jest bezużyteczny w druku. Miniatura zostaje, bo pomaga rozpoznać opakowanie. */
    .prose a[href^="/produkty/"],
    .prose a[href^="/zabiegi/"] {
        background: transparent;
        border: 0;
        color: #000;
        padding: 0;
        font-weight: 600;
    }

    .prose a[href^="/produkty/"] img[src$="/zdjecie"] { border-color: #999; }

    /* Krok pielęgnacyjny nie powinien się rozjeżdżać na dwie strony. */
    .prose li, .prose h2, .prose h3 { break-inside: avoid; }
    .prose h2, .prose h3 { break-after: avoid; }

    /* Adresy linków nie są potrzebne - klientka czyta plan, nie nawiguje po nim. */
    a { text-decoration: none; }
}

/* Marginesy arkusza wprost, żeby nie zależeć od domyślnych w telefonie. @page musi stać
   na poziomie głównym arkusza. */
@page { margin: 14mm; }

/* Zgłoszenia usunięcia konta na liście klientek (administrator). Zgłoszenie, któremu
   zostało tydzień albo mniej do terminu z RODO, jest wyróżnione. */
.deletion-requests { border-left: 3px solid var(--warn); }
.list > li.deletion-urgent { background: var(--warn-soft); border-radius: var(--radius-sm); padding-left: .6rem; padding-right: .6rem; }
.list > li.deletion-urgent .row-sub { color: var(--warn-ink); }

/* ----- Proponowane zabiegi --------------------------------------------------- */

/* Blok propozycji w formularzu i w karcie wizyty - spokojniejszy od zaleceń: ramka w
   kolorze marki zamiast tła. */
.proposal-box {
    border: 1px dashed var(--line-strong);
    border-radius: var(--radius-sm);
    padding: .85rem 1.1rem;
    margin: .25rem 0 1rem;
}

.visit-card .proposal-box { margin-bottom: 0; }
.proposal-pending { margin-bottom: .75rem; }
.proposal-list .badge { margin-left: .4rem; }
.proposal-list li > .prose { margin-top: .35rem; font-size: .93rem; }

/* Karta propozycji u klientki. */
.proposal-card { display: flex; flex-direction: column; gap: .75rem; }
.proposal-head { display: flex; gap: 1rem; align-items: center; }
.proposal-photo { width: 72px; height: 72px; object-fit: cover; border-radius: var(--radius-sm); flex: 0 0 auto; }
.proposal-title { font-size: 1.2rem; font-weight: 500; margin: 0 0 .3rem; }
.proposal-facts { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.proposal-facts .badge { margin-left: 0; }
.proposal-facts .product-price { font-size: 1rem; }

.proposal-note {
    border-left: 3px solid var(--sage);
    padding: .1rem 0 .1rem .9rem;
}

.proposal-about summary { cursor: pointer; color: var(--accent); font-weight: 500; }
.proposal-about[open] summary { margin-bottom: .5rem; }

.proposal-decline-link { color: var(--muted); font-size: .9rem; margin-left: auto; }
/* Notatki kosmetologa w wizycie - widzi je tylko personel, więc wyglądają jak notatki
   gabinetu: ciepłe tło i plakietka "tylko dla gabinetu". */
.staff-notes-box {
    background: var(--warn-soft);
    border-left: 3px solid var(--warn);
    border-radius: var(--radius-sm);
    padding: .85rem 1.1rem;
    margin: .25rem 0 1rem;
}

.staff-notes-box .badge { margin-left: .4rem; }

/* Propozycje na karcie wizyty u klientki - nazwa, termin, a pełna karta na /me/zabiegi. */
.visit-proposals { list-style: none; padding: 0; margin: .4rem 0 0; display: flex; flex-direction: column; gap: .35rem; }
.visit-proposals .badge { margin-left: .4rem; }
.visit-proposals .row-title { display: inline; }
.visit-proposals { gap: .75rem; }
/* Delikatna kreska między zabiegami, żeby od razu było widać, że to osobne wpisy. */
.visit-proposals > li + li { border-top: 1px solid var(--sage); padding-top: .75rem; }
.visit-proposals .proposal-note { margin-top: .35rem; font-size: .95rem; }
.visit-proposals .proposal-note .prose > :last-child { margin-bottom: 0; }
/* U klientki ramka ma być wyraźna - to zaproszenie na kolejną wizytę, nie przypis. */
.proposal-box-strong { border: 2px solid var(--sage); }
.visit-section-title { font-size: 1.15rem; font-weight: 700; color: var(--accent-dark); margin: 0 0 .75rem; padding-bottom: .5rem; border-bottom: 1px solid var(--sage); }

.proposal-decline { display: inline-flex; flex-wrap: wrap; gap: .5rem; align-items: center; font-size: .9rem; color: var(--ink-soft); }

/* Opcje dodatkowe zabiegu - w edytorze wiersz na opcję, u klientki lista pod opisem. */
.option-editor { border: 0; padding: 0; margin: 0 0 1rem; }
.option-editor legend { font-size: .88rem; font-weight: 500; color: var(--ink-soft); margin-bottom: .25rem; padding: 0; }
.option-editor > .field-hint { margin: 0 0 .6rem; }
.option-row {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr) auto;
    gap: 0 .75rem;
    align-items: end;
}
.option-remove { margin-bottom: 1.1rem; color: var(--danger); }

@media (max-width: 720px) {
    .option-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    .option-row .option-name { grid-column: 1 / -1; }
    .option-remove { justify-self: start; }
}

/* Cennik wariantów na górze karty zabiegu - tabelka bez ramek, ceny w jednej kolumnie. */
.treatment-options { width: 100%; border-collapse: collapse; font-size: 1rem; margin: 0 0 1rem; }
.treatment-options th,
.treatment-options td { border: 0; padding: .3rem 0; vertical-align: baseline; background: none; }
.treatment-options th {
    text-align: left;
    font-size: inherit;
    text-transform: none;
    letter-spacing: normal;
    color: var(--ink);
    font-weight: 500;
    padding-right: 1rem;
}
.treatment-options .treatment-option-price { text-align: right; white-space: nowrap; font-weight: 600; padding-right: 1rem; }
.treatment-options .treatment-option-duration { text-align: right; white-space: nowrap; color: var(--muted); width: 1%; }

.product-link { margin: 1rem 0 0; }

/* Client portal: thumb-friendly navigation and reading on a narrow screen. */
.client-nav-icon { display: none; width: 22px; height: 22px; flex: 0 0 auto; }
.account-menu { position: relative; }
.account-menu summary, .version-disclosure > summary {
    cursor: pointer;
    padding: .65rem .8rem;
    min-height: 44px;
    color: var(--accent);
    font-weight: 600;
    border-radius: var(--radius-sm);
}
.account-menu summary:focus-visible, .version-disclosure > summary:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.account-menu-panel {
    position: absolute;
    right: 0;
    top: 100%;
    z-index: 20;
    width: min(270px, calc(100vw - 32px));
    padding: .75rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-hover);
    overflow-wrap: anywhere;
}
.account-menu-panel strong { display: block; padding: .5rem; }
.account-menu-panel a { display: flex; align-items: center; min-height: 48px; padding: .5rem; }
.version-disclosure { margin-top: 1.25rem; }
.version-disclosure > summary { background: var(--surface); }
.version-disclosure[open] > summary { margin-bottom: .75rem; }
.version-disclosure > p { margin-top: .75rem; }
.new-messages { align-self: center; margin-top: .5rem; }
.new-messages[hidden] { display: none; }
.client-thread { display: flex; flex-direction: column; }
.client-thread .thread { min-height: 8rem; }
.client-chat-help { display: none; }
.plan-print-actions { margin-top: 1.25rem; }
.plan-section-heading:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}
.plan-shortcuts {
    position: sticky;
    top: 0;
    z-index: 8;
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    padding: .6rem 0;
    margin-bottom: .75rem;
    background: var(--bg);
}
.plan-shortcuts[hidden] { display: none; }
.plan-shortcut {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    padding: .5rem 1rem;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    background: var(--surface);
    font-weight: 600;
    overflow-wrap: anywhere;
}
.plan-shortcut:hover { background: var(--accent-soft); text-decoration: none; }
.plan-section-heading { scroll-margin-top: var(--plan-shortcuts-height, 100px); }
.client-plan-reader .prose > ol { padding-left: 1.8rem; }
.client-plan-reader .prose > ol > li {
    padding: .85rem 1rem;
    margin-bottom: .8rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface-alt);
}
.client-plan-reader .prose > ol > li::marker { color: var(--accent); font-size: 1.15em; font-weight: 700; }
.client-plan-reader .prose > ol > li > :last-child { margin-bottom: 0; }
.client-thread .composer-row .poll-note { flex: 1 1 140px; }

/* The :target links still work if JavaScript is unavailable. */
body:has(.lightbox:target) { overflow: hidden; }
.lightbox { padding: 5rem 1rem; }
.lightbox-stage { position: relative; width: 100%; height: 100%; overflow: auto; display: flex; align-items: center; justify-content: center; overscroll-behavior: contain; }
.lightbox-image { flex: 0 0 auto; }
.lightbox-toolbar, .lightbox-navigation {
    position: absolute;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    left: max(1rem, env(safe-area-inset-left));
    right: max(1rem, env(safe-area-inset-right));
    color: #fff;
}
.lightbox-toolbar { top: max(.75rem, env(safe-area-inset-top)); }
.lightbox-navigation { bottom: max(.75rem, env(safe-area-inset-bottom)); }
.lightbox-toolbar .lightbox-close { position: static; font-size: 1rem; }
.lightbox .btn { min-height: 48px; }
.photo-zoomed .lightbox-stage { display: block; }
.photo-zoomed .lightbox-image { width: 200%; max-width: none; max-height: none; height: auto; }

@media (max-width: 720px) {
    /* 16px prevents automatic form zoom in iOS Safari, including sign-in. */
    input:not([type]), input[type=text], input[type=email], input[type=tel], input[type=date],
    input[type=number], input[type=search], select, textarea { font-size: 1rem; min-height: 44px; }
    .client-shell { font-size: 1rem; padding-bottom: calc(76px + env(safe-area-inset-bottom)); }
    .client-shell .container { padding-left: 1rem; padding-right: 1rem; min-width: 0; }
    .client-shell .topbar-inner { flex-wrap: nowrap; gap: .4rem; padding: .35rem 1rem; min-height: 64px; }
    .client-shell .brand { font-size: .95rem; gap: .4rem; min-width: 0; }
    .client-shell .brand-mark { height: 32px; }
    .client-shell .topbar-account { flex: 0 0 auto; }
    .client-shell .nav-row {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 30;
        border-top: 1px solid var(--line);
        padding-bottom: env(safe-area-inset-bottom);
        box-shadow: 0 -3px 18px rgba(37, 48, 40, .06);
    }
    .client-shell .nav-pills { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0; padding: .3rem .25rem; overflow: visible; }
    .client-shell .nav-pill {
        position: relative;
        flex-direction: column;
        justify-content: center;
        gap: .2rem;
        min-height: 60px;
        padding: .35rem .1rem;
        font-size: .7rem;
        border-radius: var(--radius-sm);
    }
    .client-nav-icon { display: block; }
    .client-shell .nav-pill .badge-count { position: absolute; top: 0; right: .15rem; margin: 0; min-width: 20px; padding: .05rem .25rem; font-size: .65rem; }
    .client-shell .btn, .client-shell .link-button { min-height: 44px; }
    .client-shell .btn-row { gap: .75rem; }
    .client-shell .btn { white-space: normal; text-align: center; max-width: 100%; }
    .client-shell .grid { grid-template-columns: minmax(0, 1fr); }
    .client-shell .card { min-width: 0; padding: 1rem; }
    .client-shell .tile-title { flex-wrap: wrap; }
    .client-shell .tile, .client-shell .card, .client-shell .page-head { overflow-wrap: anywhere; }
    .client-shell .row-main, .client-shell .dl dd, .client-shell .proposal-head > div { min-width: 0; }
    .client-shell .prose { overflow-wrap: anywhere; }
    .client-shell .prose table { display: block; max-width: 100%; overflow-x: auto; }
    .client-shell .prose img { max-width: 100%; height: auto; }
    .client-shell .prose a { min-width: 0; }
    .client-shell .versions a, .client-shell .footer-links a, .client-shell .proposal-about summary { display: inline-flex; align-items: center; min-height: 44px; }
    .client-shell .proposal-head { gap: .6rem; }
    .client-shell .proposal-photo { width: 56px; height: 56px; }
    .client-shell .treatment-options th { padding-right: .4rem; }
    .client-shell .treatment-options .treatment-option-price { padding-right: .4rem; }
    .plan-shortcut { flex: 1 1 auto; padding: .5rem .75rem; }
    .client-plan-reader .prose > ol > li { padding: .7rem .65rem; }

    /* One scrolling history and a composer inside the visible viewport. */
    .client-shell:has(.client-thread) { height: 100dvh; overflow: hidden; }
    .client-shell:has(.client-thread) .site-footer,
    .client-shell:has(.client-thread) .client-messages-heading,
    .client-shell:has(.client-thread) .client-thread + p { display: none; }
    .client-thread {
        position: fixed;
        top: calc(var(--client-view-top, 0px) + 72px);
        left: max(.5rem, env(safe-area-inset-left));
        right: max(.5rem, env(safe-area-inset-right));
        height: calc(var(--client-view-height, 100dvh) - 152px - env(safe-area-inset-bottom));
        min-height: 160px;
        margin: 0;
        z-index: 10;
    }
    .client-thread .card-head { flex: 0 0 auto; margin-bottom: .5rem; }
    .client-thread .card-head h2 { font-size: 1rem; }
    .client-thread .card-head .poll-note { display: none; }
    .client-chat-help { display: block; flex: 0 0 auto; font-size: .75rem; line-height: 1.4; color: var(--muted); margin-bottom: .5rem; }
    .client-thread .thread { flex: 1 1 auto; min-height: 0; max-height: none; overflow-y: auto; overscroll-behavior: contain; }
    .client-thread .composer { flex: 0 0 auto; margin-top: .6rem; gap: .4rem; }
    .client-thread .composer textarea { height: 64px; min-height: 48px; max-height: 120px; resize: none; }
    .client-thread .composer-row .poll-note { font-size: .7rem; line-height: 1.3; }
    .client-thread .alert { max-height: 25%; overflow-y: auto; margin-bottom: .5rem; }
    .client-keyboard .client-shell:has(.client-thread) .nav-row,
    .client-keyboard .client-shell:has(.client-thread) .topbar { visibility: hidden; }
    .client-keyboard .client-thread { top: calc(var(--client-view-top, 0px) + 4px); height: calc(var(--client-view-height, 100dvh) - 8px); }
}

@media print {
    .account-menu, .version-disclosure { display: none !important; }
    .client-shell { padding-bottom: 0; }
    .client-plan-reader .prose > ol > li { padding: 0; margin-bottom: .35rem; background: none; border: 0; border-radius: 0; }
    .client-plan-reader .prose > ol > li::marker { color: #000; font-size: 1em; }
}

/* ----- Panel kosmetologa: praca przy komputerze ------------------------------ */

/* Kosmetolog pracuje przy biurku: szerszy kontener, żeby edytor i katalog zmieściły się obok
   siebie. Strony klientki zostają w 1080 px. */
@media (min-width: 1200px) {
    .staff-shell .topbar-inner,
    .staff-shell .container { max-width: 1360px; }
}

/* Edytor po lewej, szablony i katalog po prawej - przyklejone, przewijane osobno. */
.md-workspace { min-width: 0; }

@media (min-width: 1100px) {
    .md-workspace.has-side {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(16rem, 22rem);
        gap: 1.25rem;
        align-items: start;
    }

    .md-side {
        position: sticky;
        top: 1rem;
        max-height: calc(100vh - 2rem);
        overflow-y: auto;
        overscroll-behavior: contain;
    }
}

/* Pasek zapisu: zawsze pod ręką na dole ekranu, ze stanem szkicu. */
.staff-save-bar { margin: 1rem 0 .5rem; padding: .75rem 0; z-index: 12; }
.staff-save-bar .staff-draft { margin-left: auto; }

.staff-draft {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    font-size: .85rem;
    color: var(--muted);
}

.draft-status { min-width: 12rem; }

/* Sekcje formularza wizyty - nagłówek mówi od razu, kto przeczyta treść. */
.form-shortcuts { display: flex; flex-wrap: wrap; gap: .4rem; margin: .25rem 0 1rem; }

.form-section {
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: .9rem 1.1rem;
    margin: 0 0 1rem;
    scroll-margin-top: 1rem;
}

.form-section.recommendation-box,
.form-section.staff-notes-box { border-top: 0; border-right: 0; border-bottom: 0; }

.form-section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    flex-wrap: wrap;
    margin-bottom: .75rem;
}

.form-section-head h3 { margin: 0; font-size: 1rem; }
.form-section-head .badge { margin-left: 0; }

details.form-section > summary { cursor: pointer; list-style: none; margin-bottom: 0; }
details.form-section > summary::-webkit-details-marker { display: none; }
details.form-section > summary h3::before { content: "▸ "; color: var(--sage-deep); }
details.form-section[open] > summary h3::before { content: "▾ "; }
details.form-section[open] > summary { margin-bottom: .75rem; }
details.form-section > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.previous-visit,
.copy-visit {
    border: 1px dashed var(--line-strong);
    border-radius: var(--radius-sm);
    padding: .6rem .9rem;
    margin-bottom: 1rem;
}

.previous-visit > summary,
.copy-visit > summary { cursor: pointer; font-weight: 500; color: var(--accent); }
.previous-visit-body,
.copy-visit-body { margin-top: .75rem; }
.previous-visit-body { max-height: 22rem; overflow-y: auto; }
.copy-visit-body select { max-width: 22rem; }

/* Podgląd zmian w planie. */
.plan-diff {
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: .5rem 0;
    margin: 0 0 1rem;
    max-height: 26rem;
    overflow-y: auto;
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-size: .85rem;
}

.diff-line { display: flex; gap: .6rem; padding: .05rem .9rem; white-space: pre-wrap; overflow-wrap: anywhere; }
.diff-mark { flex: 0 0 1ch; font-weight: 700; }
.diff-added { background: var(--ok-soft); color: var(--ok-ink); }
.diff-removed { background: var(--danger-soft); color: var(--danger-ink); text-decoration: line-through; }

/* Szablony: ulubione i podgląd przed wstawieniem. */
.template-chip { display: inline-flex; align-items: center; gap: .1rem; }
.template-chip .picker-chip[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-soft); }

.favourite-toggle {
    border: 0;
    background: none;
    color: var(--warn);
    font-size: 1.05rem;
    line-height: 1;
    padding: .25rem;
    cursor: pointer;
}

.template-preview {
    margin-top: .6rem;
    padding: .75rem .9rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    max-height: 20rem;
    overflow-y: auto;
}

.picker-recent h3 { margin: 0; font-size: .95rem; }

/* Lista klientek i skrzynka: filtry jako przełączniki. */
.client-filters { margin-bottom: .75rem; }
.filter-chips { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .9rem; }

.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .35rem .8rem;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    background: var(--surface);
    color: var(--ink-soft);
    font: inherit;
    font-size: .88rem;
    cursor: pointer;
}

.filter-chip:hover { background: var(--surface-alt); }
.filter-chip[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-dark); font-weight: 600; }

.list.is-refreshing { opacity: .6; transition: opacity .15s ease; }

/* Skrzynka: lista rozmów po lewej, otwarta rozmowa po prawej. */
@media (min-width: 960px) {
    .inbox {
        display: grid;
        grid-template-columns: minmax(16rem, 24rem) minmax(0, 1fr);
        gap: 1.25rem;
        align-items: start;
    }

    .inbox .inbox-list {
        position: sticky;
        top: 1rem;
        max-height: calc(100vh - 2rem);
        overflow-y: auto;
        margin-bottom: 0;
    }
}

.inbox { margin-bottom: 1.25rem; }
.inbox-list { margin-bottom: 1.25rem; }
.inbox-list .list > li.is-selected { background: var(--accent-soft); border-radius: var(--radius-sm); }
.inbox-list .row-link { padding: 0 .5rem; flex-wrap: nowrap; }
.inbox-preview { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; color: var(--ink-soft); }
.inbox-thread-head { display: flex; justify-content: space-between; align-items: center; gap: .75rem; flex-wrap: wrap; margin-bottom: .75rem; }
.inbox-thread-head h2 { margin: 0; }

/* Podsumowanie klientki. */
.summary-grid {
    display: grid;
    gap: .9rem;
    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
}

.summary-item {
    display: flex;
    flex-direction: column;
    gap: .2rem;
    padding: .85rem 1rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface-alt);
    color: var(--ink);
    min-width: 0;
    overflow-wrap: anywhere;
}

.summary-item:hover { border-color: var(--sage); text-decoration: none; }
.summary-label { font-size: .78rem; text-transform: uppercase; letter-spacing: .06em; color: var(--sage-deep); font-weight: 600; }
.summary-label .badge { text-transform: none; letter-spacing: normal; }
.summary-value { font-weight: 600; }
.summary-note { background: var(--warn-soft); border-color: var(--warn-line); }
.summary-note-text { white-space: pre-wrap; font-size: .92rem; }

/* Porównanie zdjęć: dwa panele obok siebie, każdy z własnym powiększeniem. */
.photo-compare-grid {
    display: grid;
    gap: 1rem;
    grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
}

.photo-compare-pane { display: flex; flex-direction: column; gap: .5rem; min-width: 0; }
.photo-compare-meta { display: flex; align-items: center; justify-content: space-between; gap: .5rem; flex-wrap: wrap; font-size: .9rem; }

.photo-compare-stage {
    height: min(70vh, 40rem);
    overflow: auto;
    border-radius: var(--radius-sm);
    background: var(--brand-forest);
    display: flex;
    align-items: center;
    justify-content: center;
}

.photo-compare-stage img { max-width: 100%; max-height: 100%; object-fit: contain; }
.photo-compare-stage.is-zoomed { display: block; }
.photo-compare-stage.is-zoomed img { max-width: none; max-height: none; width: 200%; }

@media print {
    .staff-save-bar, .staff-draft, .form-shortcuts { display: none !important; }
}

/* Formularze personelu na telefonie: pasek zapisu nad klawiaturą ekranową
   (--keyboard-inset liczy js/client-mobile.js) i bez auto-przybliżania pola edytora w iOS,
   które włącza się poniżej 16 px. */
.staff-save-bar { bottom: var(--keyboard-inset, 0px); }

@media (max-width: 720px) {
    .re-content { font-size: 1rem; }
    .staff-save-bar { gap: .4rem; padding: .5rem 0; padding-bottom: max(.5rem, env(safe-area-inset-bottom)); }
    .staff-save-bar .btn { padding: .55rem .9rem; }
    .staff-save-bar .staff-draft { margin-left: 0; width: 100%; }
    .keyboard-open .staff-save-bar { padding-bottom: .5rem; }
    .keyboard-open .staff-save-bar .staff-draft { display: none; }
}

.section-filled { margin-left: .4rem; }
.visit-history > summary { cursor: pointer; font-weight: 600; color: var(--accent); padding: .5rem 0; margin-bottom: .75rem; }
