/* ===========================================================================
   Theme.

   Two deliberately different jobs:

   LIGHT is Django admin's own palette, with one exception: the top bar,
   which is a navy-to-teal sweep ending on django's own header colour, so
   the breadcrumb strip under it still matches. Everything from the
   breadcrumb down - page, sidebar, cards, buttons, tables - is left on
   django's own shades, so nothing further down the page has to be
   re-matched to a new palette. The rest of what this file does in light
   mode is shape: cards, pill buttons, rounded inputs, spacing, the
   changelist/filter split. Clean and plain, which is what a clinical tool
   should be in daylight.

   DARK is a proper dark theme rather than Django's grey-on-charcoal,
   modelled on csfloat.com: a near-black page (#15171c), a slightly
   lifted bar (#1a1c23), cards a shade above that (#1b1d24), hairline
   borders, muted blue-grey text, and one bright blue accent (#237bff)
   used sparingly.

   Only a handful of --md-* tokens are shared by both; every component rule
   below reads those or Django's own variables, so neither theme has a
   colour hardcoded into a component.

   Loaded from admin/base_site.html so it reaches every page including the
   login screen, and after django's base.css/dark_mode.css so it wins.
   =========================================================================== */

:root {
  --md-radius: 10px;
  --md-radius-lg: 14px;
  --md-pill: 999px;

  /* How wide the navigation down the left is. Django ships a flat 275px,
     which is a sensible number on a big monitor and a quarter of the page
     on a laptop: a 1366x768 screen at the 125% scaling windows recommends
     reports 1093px, so the navigation was taking 25% of it and the work
     was being done in the rest.

     clamp, not a breakpoint: this is a question about how much room there
     is, and the answer should move with the room rather than jumping at
     one width. 19vw lands at 210px on that laptop and 243px at 1280,
     reaching django's own 275px at about 1450px and stopping there - so
     nothing changes on a large screen. The floor is what "Dati studio
     dentistico" and an "Aggiungi" link still fit in without the label
     turning into one word per line.

     Everything that has to agree with this number reads it from here:
     the panel itself, the offset it slides in and out by, and the width
     the content beside it is allowed. Django hardcodes 275, 276 and 299
     in three different rules, and changing one without the others is how
     the sidebar ends up half on the page. See the sidebar section below. */
  --bm-sidebar-width: clamp(210px, 19vw, 275px);

  /* The three theme-switch icons, as mask shapes. Kept here rather than
     inline in the rules that use them because a data URI is unreadable
     in the middle of a declaration block, and because all three have to
     be drawn on the same 24px grid to sit at the same weight beside each
     other. Colour is never set in them: they are masks, so the shape is
     all that is used and the colour comes from the element. See "The
     theme switch's three icons" below. */
  --icon-theme-auto: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='8.6' fill='none' stroke='black' stroke-width='1.9'/><path d='M12 3.4a8.6 8.6 0 0 0 0 17.2Z' fill='black'/></svg>");
  --icon-theme-light: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='4.3' fill='black'/><g fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round'><path d='M12 2.4v2.4M12 19.2v2.4M21.6 12h-2.4M4.8 12H2.4M18.79 5.21l-1.7 1.7M6.91 17.09l-1.7 1.7M18.79 18.79l-1.7-1.7M6.91 6.91l-1.7-1.7'/></g></svg>");
  --icon-theme-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M21.1 14.5A8.9 8.9 0 0 1 9.5 2.9 9.1 9.1 0 1 0 21.1 14.5Z' fill='black'/></svg>");
}

/* --- Light: Django's own colours, plus the few tokens components need --- */

:root,
html[data-theme="light"] {
  /* Light mode takes django's own breadcrumb and page colours as they
     ship. The top bar is the one exception (below); everything else here
     is the --md-* tokens components of ours need and django has no
     equivalent for. */
  --md-surface: #ffffff;
  --md-surface-sunken: #f8f8f8;

  /* --- The top bar -----------------------------------------------------
     A sweep from a deep navy at the left to django's own header teal,
     rather than one flat band of it. The bar is the full width of the
     screen and the only large field of colour on the page, and flat at
     that size reads as unfinished; a sweep gives the name at the left
     something to sit on and settles into the ordinary colour by the time
     it reaches the account links at the right.

     Same hue throughout (about 205 degrees) - only lightness moves - so
     it reads as one colour lit from the side rather than as two colours
     meeting. The end of the sweep is django's own --header-bg, untouched,
     which is why the right-hand side and the breadcrumb below it still
     agree with each other.

     It is an IMAGE over --header-bg rather than a replacement for it, so
     anything that cannot paint it still gets the flat colour, and dark
     mode turns it off by setting this to none. */
  --header-image: linear-gradient(to right, #12344f 0%, #2a5871 38%, #417690 72%);

  /* The breadcrumb strip repeats the sweep, every stop darkened by the
     same amount django's own --breadcrumbs-bg (#264b5d) is darker than
     its --header-bg (#417690). Without it the bar above went darkest
     exactly where the strip below stayed put, so the top-left corner of
     the page got darker going up and lighter going down and the two bars
     stopped looking like one piece of chrome. Right-hand end unchanged,
     which is why everything below still matches. */
  --breadcrumbs-image: linear-gradient(to right, #0b2133 0%, #193849 38%, #264b5d 72%);

  /* White, not django's gold. On the navy end of the sweep the gold read
     as a warning colour, and the practice's own name is not a warning.
     White is also what dark mode already uses, so the name looks the same
     in both. */
  --header-color: #ffffff;
  --header-branding-color: #ffffff;

  /* Django's own link blue, reused wherever a component needs an accent. */
  --md-accent: #417893;
  --md-accent-strong: #205067;
  --md-accent-soft: rgba(65, 120, 147, 0.12);
  --md-focus-ring: rgba(65, 120, 147, 0.28);

  /* The "Aggiungi ..." button at the top right of every list. Django's
     light theme paints it #747474 - a grey button for the one action on
     the page that creates something, sitting next to a Salva in the
     practice's own colour. Dark mode already had this pair; light mode
     was still on the default. */
  --object-tools-fg: #ffffff;
  --object-tools-bg: #417893;
  --object-tools-hover-bg: #205067;

  /* Pale tints and solid shades of the same hue that a few components
     need and django has no variable for. Named here rather than written
     into the components so that a business type with a palette of its
     own (Vertical.theme_stylesheet - solar's is solar/theme.css) can
     restate them alongside django's variables; every value is the one
     that component was written with, so this changes nothing on its own.
     Light mode only: the components' dark-mode rules set their own. */
  --bm-tint-bg: #E4EDF3;          /* a collapsed section's heading bar */
  --bm-tint-border: #C7DCE6;
  --bm-tint-fg: #1F4A60;
  --bm-tint-hover: #DCEAF4;       /* the sidebar's show/hide strip, hovered */
  --bm-toggle-bg: #EEF4F9;        /* ... and at rest: a shade off the page */
  --bm-today-bg: #F6F9FC;         /* the Dashboard's "Oggi" panel */
  --bm-recent-bg: #FFFDF7;        /* the Dashboard's recent clients */
  --bm-today-column: rgba(65, 120, 147, 0.055); /* today in the calendar */
  --bm-pick-bg: #2b6cb0;          /* the highlighted comune suggestion */
  --bm-history-bg: #2C5282;       /* Storia, at the foot of a form */
  --bm-history-hover-bg: #1F3F63;
  --bm-chart-incasso: #3b82c4;    /* "Incassato" in the Dati studio chart */

  /* Since 2.6.0, so a business type can restate them (solar does). Each is
     what the component looked like before, written as a token. */
  --bm-sidebar-link-fg: var(--link-fg);   /* the model names in the menu */
  --bm-panel-head-bg: var(--secondary);   /* a client-page panel's title bar */
  --bm-panel-head-fg: var(--header-link-color, #ffffff);
  --bm-panel-head-border: transparent;    /* drawn inside the bar, no size */
  --bm-panel-bg: var(--darkened-bg);      /* ... and the panel under it */
  --bm-followups-bg: #ffffff;             /* the CRM's "Da fare oggi" panel */
  --bm-pipeline-bg: #ffffff;              /* the CRM's Pipeline panel */
  --bm-stat-bg: #f8f8f8;                  /* the four figures inside it */
  --bm-addlink-fg: var(--link-fg);        /* "Aggiungi" in the menu and home */
  --bm-foot-link-fg: var(--link-fg);      /* "Apri l'agenda" etc. on the Dashboard */
  --bm-dash-btn-fg: #2F855A;              /* "Appuntamento" on the Dashboard */
  --bm-dash-btn-border: #2F855A;
  --bm-dash-btn-hover-bg: #2F855A;
  --bm-dash-btn-hover-fg: #ffffff;
  /* "+ Nuovo" in a Dashboard panel's heading: a plain link unless a
     business type makes it a pill ("initial": the link's own colours). */
  --bm-head-add-fg: initial;
  --bm-head-add-bg: initial;
  --bm-head-add-border: initial;
  --bm-head-add-hover-bg: initial;
  --bm-head-add-hover-fg: initial;
  --bm-head-add-hover-line: initial;
  /* How far the pill reaches past the heading's end. Unset: by its own
     padding, so a plain link's words stay exactly where they were; a
     business type that draws the pill sets 0px, so the pill itself
     stops where the panel's content does instead of at its border. */
  --bm-head-add-pull: initial;

  /* The filled action pills - "Aggiungi ... +" at the top right of a
     list, and the same pill elsewhere (Nuova trattativa on the board,
     Nuovo appuntamento on the agenda, Modifica dati and the round + on a
     client). They are not all the same colour in the core - django gives
     them three different variables - so here each token is "initial",
     which makes var(--bm-action-bg, <its own colour>) fall back to the
     colour that pill always had. A business type that restates them
     (solar: grey outlined pills that fill amber under the pointer) moves
     them all together. */
  --bm-action-bg: initial;
  --bm-action-fg: initial;
  --bm-action-border: initial;
  --bm-action-hover-bg: initial;
  --bm-action-hover-fg: initial;
  --bm-action-hover-border: initial;  /* default: the hover fill's colour */
  --bm-action-active-bg: initial;     /* pressed - default: as hovered */
  --bm-action-active-fg: initial;
  /* The agenda's arrows and "Oggi": the action pills' colours unless a
     business type gives them their own (solar: green). */
  --bm-nav-bg: initial;
  --bm-nav-fg: initial;
  --bm-nav-hover-bg: initial;
  --bm-nav-active-bg: initial;
  /* The menu: the page being viewed (default: django's --selected-row)
     and a wash while an entry or the show/hide strip is pressed (default:
     none). */
  --bm-sidebar-current-bg: initial;
  --bm-sidebar-press: initial;

  --md-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
  --md-shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.16);
}

/* --- Light, on a phone --------------------------------------------------
   No sweep - one flat colour, and it is the navy the desktop sweep
   starts from rather than the teal it ends on.

   A gradient needs room to be a gradient. Across a desktop bar it is a
   slow change nobody has to notice; squeezed into 390px it becomes a
   visible diagonal behind the menu button and the name, and the bar
   stops reading as one colour. So the phone takes a single colour, and
   the one worth taking is the deep end: it is the half of the sweep that
   reads as the app's own, the teal is django's default showing through,
   and a phone bar sitting on the same navy as the left of the desktop
   one makes the two obviously the same product.

   The name is white here too, for the same reason it is white on the
   desktop: against navy the old gold read as a warning colour. White on
   this navy is 12.4:1, which is comfortable at any size - the yellow it
   replaces was 4.0:1 against the teal.

   Only the flat colours change; --header-image stays off. The breadcrumb
   strip is not drawn on a phone at all (mobile-nav.css replaces the
   trail with the drawer), but its colour is set alongside so the pair
   cannot drift if it is ever brought back.

   767px, not 600: that is where mobile-nav.css replaces the whole header
   with the phone one - menu button, name, theme switch - so the two
   always change together.

   Placed between the light and dark blocks on purpose. After light, so it
   wins on a phone; before dark, so dark still wins over it at every
   width. Moving it below them turns a dark phone's bar navy. */

@media (max-width: 767px) {
  :root,
  html[data-theme="light"] {
    --header-image: none;
    --breadcrumbs-image: none;
    /* The first stop of --header-image and of --breadcrumbs-image. */
    --header-bg: #12344f;
    --breadcrumbs-bg: #0b2133;
    --header-branding-color: #ffffff;
  }
}

/* --- Dark ---------------------------------------------------------------
   Repeated verbatim under the media query and under [data-theme="dark"],
   mirroring how django ships dark_mode.css, so the in-app toggle and the
   OS setting both land here. */

@media (prefers-color-scheme: dark) {
  :root {
    --primary: #237bff;
    /* Lifted off the page colour so the sidebar's section bar reads. */
    --secondary: #23252e;
    /* Stays light: django paints #333 text on --accent in the date picker. */
    --accent: #f5dd5d;
    --primary-fg: #ffffff;

    --body-fg: #e4e7ec;
    --body-bg: #15171c;
    --body-quiet-color: #9ea7b1;
    --body-medium-color: #c3c9d1;
    --body-loud-color: #ffffff;

    --header-color: #ffffff;
    --header-branding-color: #ffffff;
    --header-bg: #1a1c23;
    --header-link-color: #ffffff;
    /* No sweep in dark mode: the bar is already a lift off a near-black
       page, and a gradient across it would read as a smudge. */
    --header-image: none;
    --breadcrumbs-image: none;

    --breadcrumbs-fg: #9ea7b1;
    --breadcrumbs-link-fg: #6ba5ff;
    --breadcrumbs-bg: #101216;

    --link-fg: #4f93ff;
    --link-hover-color: #85b6ff;
    --link-selected-fg: #85b6ff;

    --hairline-color: #23252e;
    --border-color: #2c2f39;

    /* The outline round a fieldset on a change form. --hairline-color is
       the page colour here, so the rules that frame each section in light
       mode disappeared completely in dark.

       A plain grey, not green. Green is what the app's controls are -
       Oggi, Storia, the add links - and a green rule round a section
       title said the title bar was one of them. Grey says "this is where
       the section starts" and nothing else.

       Mid-grey rather than near-white: the line only has to be findable,
       and a white one drew more attention than the title it was framing.
       It still clears --hairline-color (#23252e), which is the page
       colour here and is why these lines vanished in dark mode at all. */
    --fieldset-rule: #6b7280;

    --error-fg: #ff7a8a;

    --message-success-bg: #12291f;
    --message-warning-bg: #2b2415;
    --message-error-bg: #2e1720;

    --darkened-bg: #1b1d24;
    --selected-bg: #23252e;
    --selected-row: #1d212b;

    --button-fg: #ffffff;
    --button-bg: #2b2f3a;
    --button-hover-bg: #363b48;
    --default-button-bg: #237bff;
    --default-button-hover-bg: #3d8cff;
    --close-button-bg: #2b2f3a;
    --close-button-hover-bg: #363b48;
    --delete-button-bg: #c0392f;
    --delete-button-hover-bg: #d9483c;

    --object-tools-fg: #ffffff;
    --object-tools-bg: #237bff;
    --object-tools-hover-bg: #3d8cff;

    --md-surface: #1b1d24;
    --md-surface-sunken: #16181e;
    --md-accent: #237bff;
    --md-accent-strong: #3d8cff;
    --md-accent-soft: rgba(35, 123, 255, 0.16);
    --md-focus-ring: rgba(35, 123, 255, 0.4);
    --md-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --md-shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.55);
  }
}

html[data-theme="dark"] {
  --primary: #237bff;
  /* Lifted off the page colour so the sidebar's section bar reads. */
  --secondary: #23252e;
  /* Stays light: django paints #333 text on --accent in the date picker. */
  --accent: #f5dd5d;
  --primary-fg: #ffffff;

  --body-fg: #e4e7ec;
  --body-bg: #15171c;
  --body-quiet-color: #9ea7b1;
  --body-medium-color: #c3c9d1;
  --body-loud-color: #ffffff;

  --header-color: #ffffff;
  --header-branding-color: #ffffff;
  --header-bg: #1a1c23;
  --header-link-color: #ffffff;
  --header-image: none;
  --breadcrumbs-image: none;

  --breadcrumbs-fg: #9ea7b1;
  --breadcrumbs-link-fg: #6ba5ff;
  --breadcrumbs-bg: #101216;

  --link-fg: #4f93ff;
  --link-hover-color: #85b6ff;
  --link-selected-fg: #85b6ff;

  --hairline-color: #23252e;
  --border-color: #2c2f39;

  /* See the note on the same token under the media query above. */
  --fieldset-rule: #6b7280;

  --error-fg: #ff7a8a;

  --message-success-bg: #12291f;
  --message-warning-bg: #2b2415;
  --message-error-bg: #2e1720;

  --darkened-bg: #1b1d24;
  --selected-bg: #23252e;
  --selected-row: #1d212b;

  --button-fg: #ffffff;
  --button-bg: #2b2f3a;
  --button-hover-bg: #363b48;
  --default-button-bg: #237bff;
  --default-button-hover-bg: #3d8cff;
  --close-button-bg: #2b2f3a;
  --close-button-hover-bg: #363b48;
  --delete-button-bg: #c0392f;
  --delete-button-hover-bg: #d9483c;

  --object-tools-fg: #ffffff;
  --object-tools-bg: #237bff;
  --object-tools-hover-bg: #3d8cff;

  --md-surface: #1b1d24;
  --md-surface-sunken: #16181e;
  --md-accent: #237bff;
  --md-accent-strong: #3d8cff;
  --md-accent-soft: rgba(35, 123, 255, 0.16);
  --md-focus-ring: rgba(35, 123, 255, 0.4);
  --md-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --md-shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.55);
}

/* ===========================================================================
   Components - shape and spacing only; every colour comes from a variable
   =========================================================================== */

/* --- Header ------------------------------------------------------------- */

#header {
  padding: 14px 40px;
  border-bottom: none;
  /* The sweep, in light mode; "none" in dark, which leaves django's own
     --header-bg showing through underneath. Set as the image rather than
     the whole background so the flat colour stays as the floor. */
  background-image: var(--header-image, none);
}

#site-name a:link,
#site-name a:visited {
  color: var(--header-branding-color);
}

#user-tools {
  font-size: 0.72rem;
  letter-spacing: 0.02em;
}

/* --- Breadcrumbs -------------------------------------------------------- */

div.breadcrumbs {
  font-size: 0.78rem;
  padding: 10px 40px;
  /* The darkened half of the header's sweep; "none" in dark mode. See the
     token in the light block at the top of this file. */
  background-image: var(--breadcrumbs-image, none);
}

/* --- Collapsible sections ("Numerazione manuale") ------------------------
   The bar you click to open a section that is folded away by default.

   Django paints it in --header-bg, the same solid teal as the top bar:
   a full-width band of the app's strongest colour, given to the one
   section on the page that nobody opens. It read as the most important
   thing on a fattura and it is the least. A pale tint of the same hue
   instead, with the words in the deep end of it - still obviously a bar
   you can press, no longer the loudest thing in the room.

   The colour is written out rather than taken from --header-bg, which
   is what it used to read: that token is the top bar's, it is a
   different colour on a phone, and a section heading has no business
   changing colour with the screen size.

   Body class in the selector so this outranks django's own, which is
   in forms.css and loads in a block that can land either side of this
   file depending on the page. Dark mode keeps django's: --header-bg
   there is a near-black lift off a near-black page, which is already
   the quiet version of this. */
.change-form :not(.inline-related) .collapse summary {
  background: var(--bm-tint-bg);
  border-color: var(--bm-tint-border);
  color: var(--bm-tint-fg);
}

@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .change-form :not(.inline-related) .collapse summary {
    background: var(--header-bg);
    border-color: var(--header-bg);
    color: var(--header-link-color);
  }
}

html[data-theme="dark"] .change-form :not(.inline-related) .collapse summary {
  background: var(--header-bg);
  border-color: var(--header-bg);
  color: var(--header-link-color);
}

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

.module,
.dashboard-col,
.inline-related fieldset.module {
  background: var(--md-surface);
  border: 1px solid var(--hairline-color);
  border-radius: var(--md-radius);
  box-shadow: var(--md-shadow-sm);
}

.module,
.inline-related fieldset.module {
  overflow: hidden;
}

/* ...except sideways, for a table of lines. overflow:hidden is there to
   keep the contents inside the rounded corners, but on a table wider than
   its card it simply cut the last columns off: at 1280px a fattura's
   Prestazioni lost Denti and Cancella altogether, with nothing to say they
   were there. Now the card scrolls sideways instead. On a screen with
   room for the whole row nothing scrolls and nothing changes; on a phone
   the rows are cards (inline-sheet.css) and the table is parked out of
   sight, so there is nothing here to scroll. */
.inline-group .tabular fieldset.module {
  overflow-x: auto;
  overflow-y: hidden;
}

/* Three lines round each section title on a change form - over the top of
   the heading bar and down its two ends - and nothing else. Nine lines on
   a fattura: Prestazioni, Pagamenti, Note e marca da bollo.

   Dark mode only. In light mode --hairline-color already draws these and
   they read well, so there is deliberately no rule here that light mode
   can reach: the selectors below are all under a dark-mode root, and the
   previous attempt - one shared rule with a var() fallback - is gone. In
   dark mode --hairline-color is the page colour itself, so the same lines
   were simply invisible.

   The colour is a near-white, not the green these started as: see the
   note on --fieldset-rule.

   Not the heading's bottom edge and not the rest of the card: outlining
   the whole card put green round everything, which is a different thing
   from making the titles stand out.

   The card's overflow:hidden and border-radius clip the ends of the top
   line, which is what keeps it from meeting the corners. */
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .change-form #content-main .module > h2,
  html:not([data-theme="light"]) .change-form .inline-related h3 {
    border-top: 1px solid var(--fieldset-rule);
    border-left: 1px solid var(--fieldset-rule);
    border-right: 1px solid var(--fieldset-rule);
  }
}

html[data-theme="dark"] .change-form #content-main .module > h2,
html[data-theme="dark"] .change-form .inline-related h3 {
  border-top: 1px solid var(--fieldset-rule);
  border-left: 1px solid var(--fieldset-rule);
  border-right: 1px solid var(--fieldset-rule);
}

/* Only the three tables at the foot of a patient's page scroll. Scoped
   deliberately: "overflow-x: auto" alone also turns overflow-y into auto
   (the spec won't let one axis be visible while the other is not), which
   on the odontogramma panel meant the hover card counted as overflow and
   the panel grew a scrollbar of its own. */
.dashboard-grid .dashboard-col {
  overflow-x: auto;
}

/* The odontogramma's hover card has to be free to spill out of its panel
   and over whatever is next to it. */
.chart-agenda-grid .dashboard-col {
  overflow: visible;
}

/* Five columns in a third-width panel: tightening the cells lets the last
   one ("Modifica") fit outright at normal window widths, so the scrollbar
   above stays a fallback for narrow screens rather than the usual case. */
.dashboard-col table.dash-table th,
.dashboard-col table.dash-table td {
  padding: 6px 5px;
  font-size: 0.82em;
}

.dashboard-col table.dash-table th:first-child,
.dashboard-col table.dash-table td:first-child {
  padding-left: 2px;
}

/* The app-list caption is a link, and django colours caption links white
   with a more specific selector than the caption itself - which would
   leave white text on the quiet caption bar below. */
#content-main .module caption a,
#content-main .module caption a:link,
#content-main .module caption a:visited,
.module caption a {
  color: var(--body-loud-color);
}

.module > h2,
#content-main .module caption,
.inline-related h3 {
  background: var(--md-surface-sunken);
  color: var(--body-loud-color);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--hairline-color);
}

/* --- Right-hand column (Azioni recenti) ---------------------------------

   #content-related is only a column wrapper, but django fills it with
   --darkened-bg. That was invisible when the module inside it was a flat
   panel of the same colour; now the module is a white card, the wrapper's
   own fill showed as a stray grey band hanging below it. */

#content-related {
  background: none;
}

/* --- Changelist: results card and filter panel --------------------------

   Django wraps both the results and the filter sidebar in one element,
   #changelist, which also carries .module - so the card styling above put
   a single rounded box around the pair. Because the two are flex siblings,
   the box grew to whichever was taller: on a short list with a long filter
   (or the reverse) it left a large empty stretch of card with nothing in
   it, and the filter's own panel inherited a stray rounded corner where it
   met the card's edge.

   So #changelist is not a card. The results column is, and the filter is
   its own square-edged panel beside it - each ending where its own content
   ends. */

#changelist.module {
  background: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
  overflow: visible;
}

#changelist .changelist-form-container {
  background: var(--md-surface);
  border: 1px solid var(--hairline-color);
  border-radius: var(--md-radius);
  box-shadow: var(--md-shadow-sm);
  overflow: hidden;
  min-width: 0;
}

/* Narrower than django's 240px, and closer in: the width it takes comes
   straight out of the results table, which on a list with several columns
   was enough to push the last one out of sight. */
#changelist #changelist-filter {
  flex: 0 0 200px;
  margin-left: 18px;
  background: var(--md-surface);
  border: 1px solid var(--hairline-color);
  border-radius: 0;
  box-shadow: var(--md-shadow-sm);
  overflow: hidden;
  align-self: flex-start;
}

#changelist #changelist-filter h2,
#changelist #changelist-filter h3 {
  border-radius: 0;
}

/* --- Tables ------------------------------------------------------------- */

#changelist table thead th,
.results thead th {
  background: var(--md-surface-sunken);
  border-bottom: 1px solid var(--border-color);
}

/* Uppercase with generous tracking is what makes a header read as a
   header - but it also makes the header the widest thing in its column,
   so the tracking is kept modest and the size small. */
#changelist table thead th a,
.results thead th a {
  color: var(--body-quiet-color);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

/* Django holds thead th to one line, so a two-word heading like
   "Prestazione prevista" props its whole column open - and an uppercased
   heading is wider still. Letting it wrap drops the column's minimum to
   its longest single word. (Django also sets padding: 0 on thead th and
   puts the padding on the link inside; don't override that or every
   column gets wider.) */
#changelist table thead th {
  white-space: normal;
}

#changelist tbody tr:hover > * {
  background: var(--selected-row);
}

/* Sort controls.

   Django floats them beside a block heading with 9px of top padding, so a
   sorted column's header grew taller than its neighbours and the heading
   itself could drop below the float. Sorting a column should not move the
   header row at all - so the controls come out of flow entirely, pinned to
   the right of the cell and vertically centred. Out of flow means they
   cost no height, and the small gutter reserved below is the only width
   they take from the column. */
#changelist table thead th {
  position: relative;
  vertical-align: middle;
}

#changelist table thead th .text {
  display: block;
}

#changelist table thead th.sortable .text,
#changelist table thead th.sorted .text {
  padding-right: 20px;
}

#changelist table thead th .sortoptions {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  float: none;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0;
  margin: 0;
}

/* The column the list is sorted by shows both of its controls all the
   time (2.6.1): the arrow saying which way it is sorted, and before it
   the barred arrows that take the sort off. Django showed the second
   only under the pointer, so nobody knew it was there, and drew it over
   the end of the heading's own highlighted box. Here the heading leaves
   room for both (6px from the cell's edge, 14px each, 4px between, 6px
   before the heading's box ends), and the icons are django's own -
   same shapes, same colours. */
#changelist table thead th.sorted .text {
  padding-right: 44px;
}

#changelist table thead th.sorted a.sortremove {
  visibility: visible;
}

/* The float's clearing div has nothing left to clear, and it added a stray
   line box to every header. */
#changelist table thead th .clear {
  display: none;
}

/* --- Date hierarchy ("‹ Tutte le date | Luglio 2026 | ...") ------------- */

/* Django gives #toolbar a 15px bottom margin, which made sense when the
   search box was its own free-standing block. Inside the results card it
   is just a gap between the search row and the date links, on top of this
   nav's own padding. */
#changelist #toolbar {
  margin-bottom: 0;
}

/* The magnifier before the search box (2.6.0). Django sets it inline on
   the text's baseline, which left it a pixel or two low of the box beside
   it, and with 10px of toolbar before it and the label's own margin and a
   space after it, off-centre in the strip between the card's edge and the
   box. One flex line instead: everything on the box's middle, and the
   same 6px either side of the glyph, so it sits in the middle of its gap
   and the box starts a little further left. Below 1024px responsive.css
   already lays this row out the same way (with its own gaps). */
#changelist #toolbar {
  padding-left: 10px;
}

#changelist #toolbar #changelist-search > div {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 10px;
}

#changelist #toolbar #changelist-search label[for="searchbar"] {
  display: flex;
  flex: 0 0 auto;
}

#changelist #toolbar #changelist-search label[for="searchbar"] img {
  display: block;
  margin: 0;
}

#changelist .toplinks {
  padding: 11px 16px;
  gap: 6px 18px;
  align-items: center;
}

/* The guillemet is part of the link text, so without this it sits flush
   against the card edge with a single thin space after it. */
#changelist .toplinks .date-back {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  font-weight: 600;
}

/* --- Filter panel ------------------------------------------------------- */

/* Django pins the eye icon 1px from the top of a block-level link, so it
   floats above the text. Laying the link out as a flex row centres the
   text, and centring the background on the same box puts the icon on the
   same line. Both classes: the link becomes .hidelink once counts are on. */
#changelist-filter .viewlink,
#changelist-filter .hidelink {
  display: inline-flex;
  align-items: center;
  min-height: 20px;
  padding-left: 21px;
  background-position: 0 50%;
  background-size: 15px 15px;
}

/* --- The drawn "+" ------------------------------------------------------
   See templates/admin/clinic/_plus.html for why it is drawn rather than
   typed. Here, in brand.css, because every page in the app loads this one
   file and add controls are on most of them.

   1em square by default and sized down where it sits inside a round
   button - the rules for those are with the buttons themselves, in
   admin_overrides.css and on the client page. */
.icon-plus {
  display: inline-block;
  width: 1em;
  height: 1em;
  /* Never squashed by a flex parent, whatever else is in the button. */
  flex: 0 0 auto;
  vertical-align: -0.125em;
}

/* --- The theme switch's three icons --------------------------------------
   Auto, light and dark, drawn here instead of django's.

   Django's are a half-filled disc, a sun whose rays are eight separate
   rectangles pinned round a ring, and a moon cut from a square - all
   drawn at 24px and all reading as slightly wrong at the 1.5rem they are
   shown at: the sun's rays touch its body, the moon's crescent is
   thicker on one horn than the other.

   Replaced through the mask property rather than by overriding django's
   <symbol> definitions: those live at the foot of base.html, referenced
   by id, and the first element with an id wins - so a second copy cannot
   take their place without copying the whole template. Masking the <svg>
   box and hiding the <use> inside it needs no template at all.

   background-color: currentColor, so all three take the header's own
   colour and follow the theme - which is the thing a background-image
   could not do. */

.theme-toggle svg use {
  display: none;
}

/* NOT currentColor, which is what the first attempt at this used and why
   the switch went blank: django sets `color: var(--header-bg)` on these
   three, because its own symbols carry a backing shape that has to match
   the bar. currentColor there is the bar's own colour, so the icon was
   painted in the colour behind it.

   --header-link-color is the colour django means the icon to be, and it
   is already right in both themes and on a phone.

   Django's own three-selector rule sets fill and color on exactly these
   three classes; matching it selector for selector keeps the weights
   even, and this file loads after dark_mode.css. Django's display
   rules - one icon shown, two hidden, by [data-theme] - are untouched. */
.theme-toggle svg.theme-icon-when-auto,
.theme-toggle svg.theme-icon-when-dark,
.theme-toggle svg.theme-icon-when-light {
  background-color: var(--header-link-color, #ffffff);
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

/* Auto: a disc with one half filled - django's own idea, drawn with a
   proper rim so the filled half does not read as a bite out of it. */
.theme-toggle svg.theme-icon-when-auto {
  -webkit-mask-image: var(--icon-theme-auto);
  mask-image: var(--icon-theme-auto);
}

/* Light: a solid disc with eight rounded rays, set clear of it. */
.theme-toggle svg.theme-icon-when-light {
  -webkit-mask-image: var(--icon-theme-light);
  mask-image: var(--icon-theme-light);
}

/* Dark: one crescent, cut by a circle of the same radius offset along the
   diagonal, so both horns come to the same point. */
.theme-toggle svg.theme-icon-when-dark {
  -webkit-mask-image: var(--icon-theme-dark);
  mask-image: var(--icon-theme-dark);
}

/* --- Segmented switch ---------------------------------------------------
   Two mutually exclusive views of the same thing, shown as one control
   rather than as two separate buttons: the teeth picker's Permanenti /
   Decidui, the odontogramma's.

   The shape is .agenda-switch's (agenda.css), which is this same control
   built out of links because its options are real URLs. These options are
   not - they change what is on screen without leaving the page - so they
   are real radio inputs. Radios rather than javascript-toggled buttons
   because the behaviour this control is supposed to have is a radio
   group's: arrow keys move between the options and the whole group is one
   tab stop, both for free.

   The input is moved out of sight rather than hidden, because
   display:none would take it out of the tab order with it.

   Every size and spacing below is written out rather than inherited.
   These labels sit inside admin forms, where ".aligned label" gives every
   label a fixed 160px column - which is right for a field's name and
   wrong for a segment of a switch. Hence the selectors carrying the
   element name: they have to outrank that rule wherever this control is
   used. */
.seg-switch {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--border-color);
  border-radius: 8px;
  overflow: hidden;
  background: var(--md-surface);
}

.seg-switch label.seg-switch-option {
  position: relative;
  display: flex;
  float: none;
  width: auto;
  min-width: 0;
  margin: 0;
  padding: 0;
  font-weight: 600;
}

.seg-switch label.seg-switch-option + label.seg-switch-option {
  border-left: 1px solid var(--border-color);
}

.seg-switch label.seg-switch-option > input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  border: 0;
  clip-path: inset(50%);
  overflow: hidden;
}

.seg-switch label.seg-switch-option > span {
  display: flex;
  align-items: center;
  padding: 8px 16px;
  font-size: 0.8rem;
  line-height: 1.2;
  white-space: nowrap;
  color: var(--body-fg);
  cursor: pointer;
  transition: background-color 0.12s ease, color 0.12s ease;
}

.seg-switch label.seg-switch-option > span:hover {
  background: var(--darkened-bg);
}

.seg-switch label.seg-switch-option > input:checked + span {
  background: var(--button-bg);
  color: var(--button-fg);
}

.seg-switch label.seg-switch-option > input:focus-visible + span {
  outline: 2px solid var(--md-accent);
  outline-offset: -2px;
}

@media (prefers-reduced-motion: reduce) {
  .seg-switch label.seg-switch-option > span { transition: none; }
}

/* --- Rows you type into -------------------------------------------------

   The tables of an edit page where rows are added and filled in - the
   prestazioni and pagamenti of a fattura, the lines of a preventivo, an
   installation's pratiche - are forms, not lists to read across: every
   row is on the same plain surface. Django stripes them like a table of
   data, which made one line of the form look different from the next for
   no reason. The frame around them stays grey - the section's title, the
   column headings and the "+ Aggiungi" row - so the start and the end of
   the section are still plain to see.

   Only these tables. The lists (Fatture, Agenda...) keep their stripes:
   there they help the eye follow a row across a wide page. */
.inline-group .tabular tbody tr.form-row,
.inline-group .tabular tbody tr.row-form-errors {
  background: var(--body-bg);
}

.inline-group .tabular tbody tr.add-row {
  background: var(--darkened-bg);
}

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

.button,
a.button,
input[type="submit"],
input[type="button"],
button,
.submit-row input,
.submit-row a,
.object-tools a {
  /* Before anything else: stop the browser drawing its own button.

     iOS gives every <button> a native bezel - a pale rounded rectangle -
     and paints it UNDER whatever css puts on top, so the green Salva
     arrived with a white plate around it that stayed until the first
     repaint. It only showed there because that is the app's first real
     <button>; everything else is an <a> or an <input type=submit>, which
     ios leaves alone. */
  appearance: none;
  -webkit-appearance: none;
  border: none;
  border-radius: var(--md-pill);
  padding: 9px 20px;
  font-weight: 600;
  font-size: 0.8rem;
  letter-spacing: 0.01em;
  line-height: 1.2;
  cursor: pointer;
  transition: background-color 0.15s ease, box-shadow 0.15s ease,
    transform 0.06s ease, filter 0.15s ease;
}

.button:active,
input[type="submit"]:active,
button:active,
.object-tools a:active {
  transform: translateY(1px);
}

/* The one primary action on a page gets a little more presence - the
   colour is django's own default-button variable, not a colour of ours. */
.submit-row input[type="submit"].default,
.submit-row input[name="_save"],
#login-form .submit-row input[type="submit"] {
  padding: 11px 30px;
  box-shadow: var(--md-shadow-sm);
}

/* Written against :link/:visited on purpose. Django styles these buttons
   with ".object-tools a:link, .object-tools a:visited", which outranks a
   plain ".object-tools a" - so the sizing below was being ignored
   entirely and the buttons kept django's cramped 3px/12px box. */
.object-tools a:link,
.object-tools a:visited {
  /* Sized to sit in the same family as Salva and the other real buttons -
     django's own box here is 3px/12px at 11px type, which next to a 9px/
     20px submit button reads as a link someone made rectangular. Still a
     step below the submit row, since this one lives up in the heading. */
  display: inline-flex;
  align-items: center;
  float: none;
  padding: 8px 18px;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-transform: none;
  border-radius: var(--md-pill);
  box-shadow: var(--md-shadow-sm);
}

.object-tools a:link:hover,
.object-tools a:visited:hover {
  box-shadow: var(--md-shadow-lg);
}

/* django gives each item a fixed 1rem height, sized for its own 19px
   button; anything taller hangs out of the bottom of the li and the row
   stops lining up with the heading beside it. */
.object-tools li {
  height: auto;
  display: flex;
  align-items: center;
}

/* Django lifts this row by -48px, measured against its own 19px button.
   Ours is 31px, so the number has to be re-derived rather than nudged:
   the value below is the one that puts the middle of the buttons on the
   middle of the <h1> beside them. Kept in px, not rem, because the
   heading's own box grows with the root size at a different rate than
   the button's does - a rem value lands right at 16px and drifts by 4px
   on a 4K desktop, where a fixed one stays inside a pixel or two. */
.object-tools {
  margin-top: -50px;
}

/* The add / view-site glyphs are background images pinned to the right
   edge, so the right padding has to clear them by hand. 18 to the edge
   matches the padding on the left, 13 is the glyph, 8 is the gap after
   the label - so the label and the glyph read as one group centred in the
   pill, rather than text shoved left of a floating symbol. */
.object-tools a.viewsitelink:link,
.object-tools a.viewsitelink:visited {
  padding-right: 39px;
  background-position: right 18px center;
  background-size: 13px 13px;
}

/* The filled action pills' colours, through the --bm-action-* tokens
   (see their note at the top of this file): django's own colours unless a
   business type restates them. The outline is an inset shadow, so a pill
   with one is exactly the size of a pill without; under the pointer it
   takes the fill colour and disappears into it. Not the outlined
   secondary tools beside them (.objtool-secondary), which keep theirs,
   nor Storia. The fallbacks are the default-button pair, which is what
   admin_overrides.css has always given these pills (see the note there). */
.object-tools a:not(.objtool-secondary):not(.historylink):link,
.object-tools a:not(.objtool-secondary):not(.historylink):visited {
  background-color: var(--bm-action-bg, var(--default-button-bg));
  color: var(--bm-action-fg, var(--button-fg));
  box-shadow: inset 0 0 0 1px var(--bm-action-border, transparent), var(--md-shadow-sm);
}

.object-tools a:not(.objtool-secondary):not(.historylink):hover,
.object-tools a:not(.objtool-secondary):not(.historylink):focus {
  background-color: var(--bm-action-hover-bg, var(--default-button-hover-bg));
  color: var(--bm-action-hover-fg, var(--button-fg));
  box-shadow: inset 0 0 0 1px var(--bm-action-hover-border, var(--bm-action-hover-bg, transparent)), var(--md-shadow-lg);
}

.object-tools a:not(.objtool-secondary):not(.historylink):active,
.object-tools a:not(.objtool-secondary):not(.historylink):link:active,
.object-tools a:not(.objtool-secondary):not(.historylink):visited:active {
  background-color: var(--bm-action-active-bg, var(--bm-action-hover-bg, var(--default-button-hover-bg)));
  color: var(--bm-action-active-fg, var(--bm-action-hover-fg, var(--button-fg)));
  box-shadow: inset 0 0 0 1px var(--bm-action-active-bg, var(--bm-action-hover-border, var(--bm-action-hover-bg, transparent))), var(--md-shadow-sm);
}

/* The "Aggiungi ..." pill's + is drawn the way the other Aggiungi links'
   is (see "The + Aggiungi links" below): its own small box after the
   words, on their x-height middle, rather than a background centred on
   the pill - which is centred on the line box, and in Segoe UI the
   letters do not sit in the middle of their line box, so the + rode off
   the words. Same size and the same 8px gap and 18px end padding as
   before, so the pill is exactly as wide as it was.

   The pill stays a flex line (so a template's stray spaces around the
   label never widen the gap), lined up on the text's baseline: the
   glyph's box then stands on that baseline, and the transform lifts its
   middle to half an x-height above it - what vertical-align: middle does
   on an ordinary line - plus the same small nudge towards the capitals.
   A transform moves nothing else, so the pill's height is the text's. */
.object-tools a.addlink:link,
.object-tools a.addlink:visited {
  align-items: baseline;
  padding-right: 18px;
  background-image: none;
}

.object-tools a.addlink::after {
  content: "";
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
  /* The negative top margin keeps the glyph, standing on the baseline,
     from making the line taller than the words: a 13px box reaches
     higher above the baseline than these letters do. */
  margin: -6px 0 0 8px;
  transform: translateY(calc(6.5px - 0.5ex - 0.06em));
  /* Painted in the text's own colour through django's glyph as a mask,
     so it follows the pill: white on a filled one, grey on an outlined
     one, white again under the pointer. */
  background-color: currentColor;
  -webkit-mask: url("../admin/img/tooltag-add.e59d620a9742.svg") center / contain no-repeat;
  mask: url("../admin/img/tooltag-add.e59d620a9742.svg") center / contain no-repeat;
}

/* A secondary tool: a different way to look at the same records, as
   opposed to the filled pill next to it that creates a new one. Outlined
   and squarer, matching "Vista elenco" on the calendar's toolbar - the two
   directions of the same switch, so they read as the same control.
   Written against :link/:visited because django's own rule for these is,
   and that outranks a plain class. */
.object-tools a.objtool-secondary:link,
.object-tools a.objtool-secondary:visited {
  background: transparent;
  background-image: none;
  color: var(--link-fg);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  /* One pixel off the filled pill's padding, top and bottom, because this
     one carries a border and the other doesn't - so the two finish the
     same height and the pair sits on one line. */
  padding: 7px 17px;
  box-shadow: none;
}

.object-tools a.objtool-secondary:link:hover,
.object-tools a.objtool-secondary:visited:hover {
  box-shadow: none;
  border-color: var(--md-accent);
}

.object-tools a.objtool-secondary:focus,
.object-tools a.objtool-secondary:hover {
  background: var(--darkened-bg);
  color: var(--link-fg);
}

.object-tools a:focus-visible,
.button:focus-visible,
input[type="submit"]:focus-visible,
button:focus-visible {
  outline: 3px solid var(--md-focus-ring);
  outline-offset: 2px;
}

/* --- Form fields -------------------------------------------------------- */

input[type="text"],
input[type="password"],
input[type="email"],
input[type="url"],
input[type="number"],
input[type="tel"],
input[type="date"],
input[type="time"],
textarea,
.vTextField {
  border: 1px solid var(--border-color);
  border-radius: 8px;
  padding: 8px 11px;
  background: var(--md-surface);
  color: var(--body-fg);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* Selects get the same box as the inputs beside them - but only inside a
   form. Django pins every select to a fixed 1.875rem (30px) height, and
   with this file's field padding that left about 12px of content box for
   13px text, slicing the label off top and bottom; so here the height has
   to give rather than the padding.

   Scoped to forms deliberately. The changelist's own "Azione" select is
   already sized by django's changelist CSS (24px, its own padding), so it
   never had the clipping problem - and releasing its height made that
   whole actions bar 11px taller for nothing. */
.form-row select,
.aligned select {
  height: auto;
  min-height: 36px;
  padding: 7px 10px;
  border: 1px solid var(--border-color);
  border-radius: 8px;
  background: var(--md-surface);
  color: var(--body-fg);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* Every other select keeps django's compact sizing; only the corner is
   rounded to match the rest of the controls. */
select {
  border-radius: 6px;
}

input[type="text"]:focus,
input[type="password"]:focus,
input[type="email"]:focus,
input[type="number"]:focus,
input[type="tel"]:focus,
input[type="date"]:focus,
input[type="time"]:focus,
textarea:focus,
select:focus,
.vTextField:focus {
  border-color: var(--md-accent);
  box-shadow: 0 0 0 3px var(--md-focus-ring);
  outline: none;
}

/* --- Notes boxes -------------------------------------------------------
   A "Note" box is as wide as the boxes above it, so the column of fields
   ends on one straight edge. Django sizes a textarea by its 40 columns
   (319px), which ran past the 284px text boxes on the client form and
   stopped short of the 416px record pickers on the installation and the
   activity.

   The widest box on the form sets the width:
   - a form of text boxes: 20em, the width django gives .vTextField. The
     textarea shares the text boxes' font, padding and border (the rule at
     the top of this section, and django's own under 1024px), so the same
     20em is the same outer edge at every size;
   - a form with a record picker (Cliente, Preventivo...): 26rem, the
     picker's own width (fk-search.css). Before fk-search.js has run the
     picker is still django's select.admin-autocomplete, so that counts too.

   Two lines tall by default (rows=2 on every notes widget). It can still
   be dragged taller, but not wider: the straight edge is the point.

   Only a stacked form's own rows - not a table of lines, not a box in a
   row of several. Nothing to add for a phone: django enlarges the font
   there and 20em grows with the text boxes it matches, while max-width
   keeps a picker-wide box inside a narrow card. */
.aligned .form-row > div > .flex-container:not(.fieldBox) > textarea {
  width: 20em;
  max-width: 100%;
  resize: vertical;
}

form:has(.aligned .form-row .fk-search, .aligned .form-row select.admin-autocomplete)
  .aligned .form-row > div > .flex-container:not(.fieldBox) > textarea {
  box-sizing: border-box;
  width: 26rem;
}

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

ul.messagelist li {
  border-radius: var(--md-radius);
  border: 1px solid var(--hairline-color);
  font-size: 0.82rem;
  padding: 12px 16px 12px 42px;
}

/* --- Login -------------------------------------------------------------- */

.login #container {
  border: 1px solid var(--hairline-color);
  border-radius: var(--md-radius-lg);
  box-shadow: var(--md-shadow-lg);
  overflow: hidden;
  width: 30rem;
  max-width: 92vw;
}

.login #header {
  padding: 18px 22px;
  border-radius: 0;
}

.login #content {
  padding: 26px 32px 30px;
}

.login .form-row {
  padding: 0;
  margin-bottom: 14px;
}

.login .form-row label {
  display: block;
  margin-bottom: 5px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--body-quiet-color);
}

.login .form-row input {
  width: 100%;
  box-sizing: border-box;
  padding: 11px 13px;
}

.login .submit-row {
  padding: 6px 0 0;
  margin: 0;
  text-align: center;
}

/* Django's login submit carries no .default class, so it picks up the
   neutral button colour - which in light happens to look primary and in
   dark is plain grey. It is the only action on the page; give it the
   primary colour explicitly. */
.login .submit-row input[type="submit"] {
  width: 100%;
  padding: 12px 24px;
  font-size: 0.88rem;
  background: var(--default-button-bg);
  color: var(--button-fg);
}

.login .submit-row input[type="submit"]:hover {
  background: var(--default-button-hover-bg);
}

/* --- Sidebar ------------------------------------------------------------

   The sidebar is navigation, not content, so it is not a card. Giving it
   the card's border, radius and clipped overflow put a rounded corner on
   the section bar (which should read as full-bleed) and left a hairline
   of border showing to either side of it - the stray little lines around
   the section heading. */

#nav-sidebar .module {
  background: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
  overflow: visible;
}

/* Every row of the navigation on the same grey. Django stripes it like a
   table of data (white, grey, white...), but it is a menu, not rows to
   read across: the stripes only made neighbouring entries look like they
   belonged to different groups. The page being viewed keeps its own
   highlight (django's .current-model, which outranks this). */
#nav-sidebar table tbody tr,
#nav-sidebar table > tr {
  background: var(--darkened-bg);
}

/* The page being viewed: django's own --selected-row unless a business
   type sets a menu colour of its own (solar: a light grey, where django's
   is a cream that read as amber on an amber theme). The dark roots below
   outrank it. */
#nav-sidebar .current-model {
  background: var(--bm-sidebar-current-bg, var(--selected-row));
}

/* In dark mode the page being viewed was told apart from its neighbours
   by a shade (#1d212b) only a step off the grey the rows now all share,
   which left it all but invisible. The dark theme's own accent wash
   instead - the same one its selected controls use. Light mode keeps
   django's yellow. */
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) #nav-sidebar .current-model {
    background: var(--md-accent-soft);
  }
}

html[data-theme="dark"] #nav-sidebar .current-model {
  background: var(--md-accent-soft);
}

/* The handle that folds the navigation away.

   In LIGHT mode django gives it the same grey wash it gives a row of a
   table, so the one control whose whole job is to change the shape of
   the page answered no more loudly than a list row does. A pale blue
   instead - a tint rather than a fill, so it lights up without turning
   into a solid bar down the side of the page, and the chevron keeps its
   own link colour rather than being reversed out to white.

   In DARK mode django's own wash is already right: the page is nearly
   black and --darkened-bg is a visible lift off it. Any blue at all
   there reads as a second accent competing with the one blue the dark
   theme uses, so the two dark roots put it straight back.

   It fades rather than switching: this is a 23px target running the
   height of the page, and a hard change at that size reads as a flicker
   every time the pointer crosses it on the way somewhere else.

   Focus gets the same fill, so a keyboard gets the same answer as a
   mouse - on top of the focus ring, not instead of it.

   At rest it is tinted too (2.6.0): django left it the page's own white,
   so the strip was invisible until the pointer happened to cross it. A
   shade darker than what is round it - light blue on dental, light amber
   on solar (--bm-toggle-bg) - says it is there; the hover colour above
   it is still the darker answer to the pointer. Light only, like the
   hover: the dark roots put django's own background back. */
.toggle-nav-sidebar {
  background-color: var(--bm-toggle-bg);
  transition: background-color 0.15s ease;
}

@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .toggle-nav-sidebar {
    background-color: var(--body-bg);
  }
}

html[data-theme="dark"] .toggle-nav-sidebar {
  background-color: var(--body-bg);
}

.toggle-nav-sidebar:hover,
.toggle-nav-sidebar:focus {
  background-color: var(--bm-tint-hover);
}

@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .toggle-nav-sidebar:hover,
  html:not([data-theme="light"]) .toggle-nav-sidebar:focus {
    background-color: var(--darkened-bg);
  }
}

html[data-theme="dark"] .toggle-nav-sidebar:hover,
html[data-theme="dark"] .toggle-nav-sidebar:focus {
  background-color: var(--darkened-bg);
}

/* Pressed - the strip, or an entry of the menu: a wash of its own while
   the button is down (solar: light amber, against the greys at rest and
   under the pointer). Laid over the background rather than replacing it
   (an inset shadow on the strip, an image on the row), so where it is
   unset - transparent - nothing changes at all, whatever each row's own
   background is. On the row rather than its cells, which are not all as
   tall as it. :active holds on a row while one of its links is pressed.
   Light mode only: the token is set only there. */
.toggle-nav-sidebar:active {
  box-shadow: inset 0 0 0 100vmax var(--bm-sidebar-press, transparent);
}

#nav-sidebar table tr:active {
  background-image: linear-gradient(var(--bm-sidebar-press, transparent), var(--bm-sidebar-press, transparent));
}

@media (prefers-reduced-motion: reduce) {
  .toggle-nav-sidebar { transition: none; }
}

/* The width, and the two numbers that have to agree with it.

   Django writes 275px, -276px and -276px into this one rule and 299px
   into another (275 + the 23px collapse handle + 1px of border), all of
   them literal. The panel is only in the right place when all four
   agree, so all four are derived from --bm-sidebar-width - see the note
   on that token for why it is not a fixed number any more.

   The 1px is the sidebar's own right-hand border: it slides fully off
   the page rather than leaving a hairline down the left edge when it is
   collapsed.

   Also: django gives this `overflow: auto`, which means both axes, so a
   row a few pixels too wide put a scrollbar across the bottom of the
   navigation. The rows are made to fit (see the note on the label column
   below), so there should be nothing to scroll to sideways - this is the
   guarantee that a longer label added later cannot bring the bar back.
   It wraps instead. Vertical scrolling is untouched: a long list of
   models still scrolls, which is what the `auto` was there for. */
#nav-sidebar {
  flex: 0 0 var(--bm-sidebar-width);
  left: calc((var(--bm-sidebar-width) + 1px) * -1);
  margin-left: calc((var(--bm-sidebar-width) + 1px) * -1);
  overflow-x: hidden;
  overflow-y: auto;
}

[dir="rtl"] #nav-sidebar {
  left: 0;
  margin-left: 0;
  right: calc((var(--bm-sidebar-width) + 1px) * -1);
  margin-right: calc((var(--bm-sidebar-width) + 1px) * -1);
}

/* What the page beside it gets. Django's 299px is 275 + the 23px handle
   + 1px of border; the same sum, with the width read from the token. Get
   this wrong and the content either overlaps the navigation or leaves a
   band of empty page down its side. */
.main.shifted > #nav-sidebar + .content {
  max-width: calc(100% - var(--bm-sidebar-width) - 24px);
}

/* ...except on a phone, where there is no sidebar to leave room for.

   Django hides it below 767px and hands the width back with a rule of
   its own - the same selector as the one above, with max-width: 100%.
   That rule is in nav_sidebar.css, which base.html links in <head>
   BEFORE brand.css: same selector, same weight, and this file is the
   one that loads last, so the rule above was quietly beating it at
   every width.

   The result on a phone was a page holding 100% - 234px: the content
   squeezed into half the screen with a band of empty page beside it,
   while the top bar - which is not inside .content - still ran the full
   width. It looked like the layout had collapsed rather than like a
   width being subtracted, which is why it read as "completely broken".

   Django's own two lines, restated here so the last word is the right
   one. They have to stay a copy of django's, not a variation on it. */
@media (max-width: 767px) {
  .main > #nav-sidebar + .content,
  .main.shifted > #nav-sidebar + .content {
    max-width: 100%;
  }
}

#nav-sidebar .module caption,
#nav-sidebar .current-app .section {
  border-radius: 0;
}

/* Django gives the filter box width:100%, so it ran edge to edge against
   the sidebar's sides and sat right up under the breadcrumb bar. Inset on
   all four sides so it reads as a control inside the panel. */
#nav-sidebar #nav-filter {
  width: calc(100% - 24px);
  margin: 16px 12px 12px;
  padding: 6px 10px;
  font-size: 0.8rem;
  border-radius: 8px;
}

#nav-filter:focus {
  border-color: var(--md-accent);
  box-shadow: 0 0 0 3px var(--md-focus-ring);
}

/* The "Aggiungi" links down the sidebar. Two things were off:

   - django draws the + as a background image pinned to "0 1px", which
     aligns it to the top of the line box rather than to the text on it,
     so on a 16px line the glyph sat a couple of pixels high of the word
     next to it. inline-flex with a vertically centred background lines
     the two up whatever the row height, including the rows whose model
     name wraps onto two lines.
   - the links started at the cell's 8px padding, which left them adrift
     in the middle of the sidebar rather than lining up with anything.
     Ranged right against a proper gutter, they form a single edge. */
/* The rows themselves.

   Django forces both the sidebar table and the label cell to width:100%,
   which fights ordinary table-cell sizing, so the row is laid out as a
   flex line instead: the label gets a fixed width rather than shrinking to
   its content, which is what makes "+ Aggiungi" land at the same x on
   every row however long the label beside it is. 178px fits "Dati studio
   dentistico", the longest label, on one line with room left for the
   button - widen it here if a longer one is ever added.

   All of this belongs in THIS file, and only here. It used to live in
   admin_overrides.css, which is attached by ModelAdmin.Media and by two
   templates; where that file lands in <head> depends on which page you
   are on (django puts {{ media }} in extrastyle on a changelist, which is
   before this file, and in extrahead on a change form or the agenda
   calendar, which is after it). With a "#nav-sidebar table td" rule in
   both files - same selector, same specificity - the winner changed from
   page to page, and the "+ Aggiungi" buttons visibly jumped sideways when
   you opened the calendar. Keep every sidebar declaration here: brand.css
   is linked once, from base_site.html, on every page. */
#nav-sidebar table tbody tr,
#nav-sidebar table > tr {
  display: flex;
  align-items: center;
  width: 100%;
}

/* 178px is what the label column WANTS, not what it insists on.

   It used to be `flex: 0 0 178px` - fixed - and django's sidebar is a
   fixed 275px with `overflow: auto` on it. 178 for the label, plus an
   "Aggiungi" link that is told never to wrap, plus the gutter, comes to
   within a few pixels of those 275; whether it fits at all came down to
   how wide the browser happened to draw that one word, which changes with
   the screen, the zoom and the windows scaling setting. When it did not
   fit, the sidebar grew a horizontal scrollbar across the bottom of the
   navigation - on some machines and not others.

   `0 1 178px` keeps the column at 178px whenever there is room, so the
   add links still form one edge down the panel, and lets it give way when
   there is not: the label wraps (it already has overflow-wrap) instead of
   pushing the row wider than the panel. min-width: 0 is what actually
   permits the shrink - a flex item will not go below its content's
   minimum width without it. */
#nav-sidebar table th {
  display: block;
  flex: 0 1 178px;
  min-width: 0;
  width: auto !important;
  padding: 14px 8px 14px 16px;
  overflow-wrap: break-word;
  box-sizing: border-box;
  /* Match the app-name header above these rows - django's own CSS already
     uppercases that .module caption, and these model-name rows did not get
     the same treatment. */
  text-transform: uppercase;
}

/* The cell shrinks to its content, so without the auto margin it sat
   immediately after the fixed-width label column, adrift in the middle of
   the panel rather than lined up with anything. margin-left:auto is what
   ranges it right in a flex row; text-align would do nothing here. The
   14px is the same inset the filter box above it has, so the panel has one
   gutter down its right-hand side. */
#nav-sidebar table td {
  display: block;
  flex: 0 0 auto;
  white-space: nowrap;
  margin-left: auto;
  padding-right: 14px;
  box-sizing: border-box;
}

#nav-sidebar table th a {
  display: block;
}

/* Django's generic "td, th { border-bottom }" for data tables leaks onto
   these cells now that they are display:block, and rendered as short
   jagged part-width lines instead of one clean rule per row. Cancelled,
   and put on the row instead. */
#nav-sidebar table th,
#nav-sidebar table td {
  border-bottom: none !important;
}

#nav-sidebar table tr:not(:last-child) {
  border-bottom: 1px solid var(--hairline-color, rgba(0, 0, 0, 0.08));
}

/* The model names. Django colours them as links; a business type can make
   them quieter (--bm-sidebar-link-fg - solar's are a dark grey, so the
   menu reads as a list of places rather than a column of orange). The
   section titles above them are captions and keep their own colour. */
#nav-sidebar table th a,
#nav-sidebar table th a:link,
#nav-sidebar table th a:visited {
  color: var(--bm-sidebar-link-fg);
}

#nav-sidebar table th a:hover,
#nav-sidebar table th a:focus {
  color: var(--link-hover-color);
}

/* The same names on the home page ("Pannello di amministrazione") and on
   an app's index page, which list the menu again: the same colour as the
   menu. (.dashboard is django's class for those two pages.) */
.dashboard #content-main .module th[scope="row"] a:link,
.dashboard #content-main .module th[scope="row"] a:visited {
  color: var(--bm-sidebar-link-fg);
}

.dashboard #content-main .module th[scope="row"] a:hover,
.dashboard #content-main .module th[scope="row"] a:focus {
  color: var(--link-hover-color);
}

/* Their "Aggiungi" words, beside the green +, through --bm-addlink-fg:
   the link colour in the core, green on solar so word and sign match. */
#nav-sidebar a.addlink:link,
#nav-sidebar a.addlink:visited,
.dashboard #content-main .module a.addlink:link,
.dashboard #content-main .module a.addlink:visited {
  color: var(--bm-addlink-fg);
}

/* --- The "+ Aggiungi" links ---------------------------------------------

   Django draws the + as a background image pinned 1px from the top of the
   link, so where it lands against the word depends on the font: with this
   app's fonts it was close, with Segoe UI on Windows it rode visibly off
   the word's middle - in the menu, on the home page, and under every table
   of lines ("+ Aggiungi prestazione"). The menu's links had been centred on
   their line box instead, which is no better: a line box's middle is not
   where the letters are either.

   So the + is its own small box before the text, set with
   vertical-align: middle - which puts its centre half an x-height above
   the baseline, the middle of the lowercase letters, in whatever font the
   browser picked. Same green glyph, django's own file.

   The "Aggiungi ..." pill at the top right of a list carries its + after
   the words instead; its own rule, further up, draws it the same way. */
#nav-sidebar a.addlink,
#content-main .module a.addlink,
.inline-group .add-row a.addlink {
  padding-left: 0;
  background: none;
  white-space: nowrap;
}

#nav-sidebar a.addlink::before,
#content-main .module a.addlink::before,
.inline-group .add-row a.addlink::before {
  content: "";
  display: inline-block;
  width: 0.95em;
  height: 0.95em;
  margin-right: 0.4em;
  vertical-align: middle;
  /* vertical-align: middle centres on the x-height; a + belongs a hair
     higher, on the line through the middle of the capitals beside it. */
  position: relative;
  top: -0.06em;
  background: url("../admin/img/icon-addlink.073aeb1feda7.svg") center / contain no-repeat;
}

/* The client column on the lists (Agenda, Fatture, Acconti, Preventivi).
   It is a column the code adds, so it can carry the business type's word
   for a client ("Paziente") - and so Django no longer gives it the
   "nowrap" class it puts on a plain foreign-key column. Same effect here,
   so a name keeps to one line as it always did. */
.field-client {
  white-space: nowrap;
}
