/* ---------------------------------------------------------------------------
   Quercia viva — the topbar.

   One line across the top of every page: where you are, the way into the
   search, and what you can do here. It replaced a two-row `.page-header` whose
   second row was an <h2> repeating the crumb above it — "Il mio calendario"
   under Home · Calendario — so the trail is now the page's name and nothing
   says it twice.

   Three pieces: the trail, the field, the corner. What the page lets you do is
   not one of them — it sits under the bar, outside the chrome — and that is
   what lets the field be centred on the *line* rather than on whatever space
   happens to be left. A search that drifts as the page's buttons change is a
   search you have to look for.

   Loaded globally from minimal.html.twig — this is chrome, like search.css.
   --------------------------------------------------------------------------- */

.qc-topbar {
  position: relative;
  background: var(--qc-card-bg);
  border-bottom: 1px solid var(--qc-divider);
}

/* The fascia reaches the menu, across a strip that is nobody's fault and
   everybody's problem.

   `html { scrollbar-gutter: stable }` (components.css §5) reserves the
   scrollbar's width — and where the platform draws overlay scrollbars it
   reserves it at *both* edges, which moves the root box 15px to the right. The
   sidebar does not move with it: it is `position: fixed`, so it is laid against
   the viewport, while the page beside it is in flow and starts 15px later. The
   gap has always been there; a transparent header simply never showed it, and
   an opaque one does — as a stripe of page between the menu and the bar.

   Painted rather than measured, because the width of that strip is a platform's
   business and not a number this stylesheet can know. It bleeds a viewport's
   worth to the left and carries the hairline with it; the sidebar is `z-index:
   1030` and covers everything beyond the strip. */
.qc-topbar::before {
  content: "";
  position: absolute;
  top: 0;
  right: 100%;
  width: 100vw;
  height: calc(100% + 1px);   /* down to and including the bar's own hairline */
  background: var(--qc-card-bg);
  border-bottom: 1px solid var(--qc-divider);
  pointer-events: none;
}

/* The middle track is stated, not inferred: an `auto` track sized by a child
   asking for a percentage of it is a circle, and the browsers that resolve it
   do not all resolve it the same way.

   The two sides are the same track written twice, and that is the whole reason
   the field is in the middle. Sized to their contents instead they come out
   different, and the field sits wherever the wider one leaves it — a couple of
   hundred pixels off centre on most pages.

   Which is only affordable because the corner holds two controls and not a
   page's worth of buttons: those are a strip of their own under the bar (see
   `.qc-pageactions`). Side by side they do not fit at all — around 500px of
   actions and 416 of field, on a line 1176 wide once the rail has had its
   share — and every way of forcing them onto one line spends the trail or the
   centring to do it. */
.qc-topbar__row {
  display: grid;
  grid-template-columns: minmax(6rem, 1fr) minmax(0, 26rem) minmax(6rem, 1fr);
  align-items: center;
  gap: 1rem;
  min-height: 3.5rem;
  padding-block: .375rem;
}

/* min-width: 0 is what lets the trail be narrowed at all — a grid item's
   automatic minimum is its content, and a long customer name would push the
   search off centre rather than fold. */
.qc-topbar__crumbs { min-width: 0; }

.qc-topbar__search {
  display: flex;
  width: 100%;
  min-width: 0;
}

.qc-topbar__end {
  justify-self: end;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: .5rem;
  min-width: 0;
}

/* A rule between the page's help and the person, and only when both are there.
   Written against the sibling rather than the person, because a page with no
   help topic has nothing to the person's left and the line would be a mark on
   its own in the corner. */
.qc-topbar__end > * + .qc-page-user {
  border-left: 1px solid var(--qc-divider);
  padding-left: .625rem;
}

/* What the page lets you do — a strip of its own between the bar and the body,
   outside the chrome.

   Right-aligned as a group, deliberately, rather than the create button being
   pushed over on its own: that only separated it from the buttons beside it and
   left them stranded at the other end. It also puts the last of them — which on
   every list here is "new" — in the corner a thumb rests in. They wrap among
   themselves, so a page with four never runs off the side. */
.qc-pageactions {
  display: flex;
  justify-content: flex-end;
  padding-top: .75rem;
}
.qc-pageactions > .btn-list {
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* ---------------------------------------------------------------------------
   The trail
   (markup: templates/base/_breadcrumb.html.twig,
    narrowing: assets/controllers/breadcrumb_controller.js)
   --------------------------------------------------------------------------- */

.qc-crumbs {
  position: relative;
  min-width: 0;
}

.qc-crumbs__list {
  display: flex;
  align-items: center;
  margin: 0;
  padding: 0;
  font-size: .8125rem;
  line-height: 1.4;
}

/* The measured state, added by the controller. Without it — no JavaScript — the
   list keeps the wrapping it has by default and the whole trail reads. */
.qc-crumbs--fitted .qc-crumbs__list {
  flex-wrap: nowrap;
  overflow: hidden;
}

/* They do not shrink, and that is what makes the trail measurable. Flex items
   give way by default, so a line that "does not fit" would quietly squeeze every
   crumb instead of overflowing, `scrollWidth` would equal `clientWidth`, and the
   controller would never see a reason to fold anything. Holding their width is
   what turns "too long" into an overflow it can read. */
.qc-crumbs__crumb,
.qc-crumbs__more {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  white-space: nowrap;
}

.qc-crumbs__crumb > a {
  color: var(--qc-text-secondary);
  text-decoration: none;
  border-radius: var(--qc-radius-sm);
  transition: color var(--qc-dur-fast) var(--qc-ease-fast);
}
.qc-crumbs__crumb > a:hover { color: var(--qc-text-primary); }
.qc-crumbs__crumb > a:focus-visible {
  outline: 2px solid var(--qc-primary);
  outline-offset: 2px;
}

/* Where you are. A link like the others — clicking it is how you leave a form
   without saving it — but it is the page's name, so it carries the weight the
   <h2> used to. */
.qc-crumbs__crumb.active > a {
  color: var(--qc-text-primary);
  font-weight: 600;
}

/* Room ran out even for the first crumb, the "…" and this one. The only crumb
   allowed to give way, and not below a width that still reads as a word. */
.qc-crumbs__crumb.is-truncated {
  flex: 0 1 auto;
  min-width: 4rem;
}
.qc-crumbs__crumb.is-truncated > a {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- The separator ----
   Bootstrap draws it with `content: var(--bs-breadcrumb-divider, "/")` on
   `.breadcrumb-item + .breadcrumb-item::before`, and Tabler layers its own
   spelling over that. Rather than chase either variable, the pseudo-element is
   claimed outright — this sheet loads after both, and this selector outranks
   theirs anyway.

   Stated as "every visible item except the first", not with the adjacent-sibling
   combinator both frameworks use, and that is the whole point. Two of the items
   in this list come and go — the folded crumbs and the "…" that stands for them
   — so "the one before me" is not the one CSS would pair me with: with the "…"
   present but empty, the second crumb was adjacent to a control rather than to
   a crumb and lost its dot; with it folded away, it was adjacent to something
   `display: none`. The first crumb is the only one that never folds, so
   `:first-child` is exactly "the start of the trail" and everything still
   standing after it wants a dot in front. */
.qc-crumbs__list { --tblr-breadcrumb-divider: "·"; --bs-breadcrumb-divider: "·"; }
/* Bootstrap pads a crumb that follows another crumb, and that pairing is the
   one this list breaks: the crumb after the "…" got the dot's margin and none
   of the padding, so the gaps along the trail came out different widths. The
   spacing is the separator's alone. */
.qc-crumbs__list > .breadcrumb-item + .breadcrumb-item { padding-left: 0; }
.qc-crumbs__list > *:not([hidden]):not(:first-child)::before {
  content: "·";
  float: none;
  padding: 0;
  margin-inline: .4rem;
  color: var(--qc-text-tertiary);
}
/* `display: flex` above would otherwise outrank the attribute's own default. */
.qc-crumbs__list > [hidden] { display: none; }

/* ---- The gathered middle ---- */

.qc-crumbs__ellipsis {
  display: inline-flex;
  align-items: center;
  padding: 0 .25rem;
  border: 0;
  border-radius: var(--qc-radius-sm);
  background: transparent;
  color: var(--qc-text-tertiary);
  font: inherit;
  line-height: 1;
  cursor: pointer;
  transition: color var(--qc-dur-fast) var(--qc-ease-fast),
              background-color var(--qc-dur-fast) var(--qc-ease-fast);
}
.qc-crumbs__ellipsis:hover,
.qc-crumbs__ellipsis[aria-expanded="true"] {
  background: color-mix(in srgb, var(--qc-primary) 8%, transparent);
  color: var(--qc-text-primary);
}
.qc-crumbs__ellipsis:focus-visible {
  outline: 2px solid var(--qc-primary);
  outline-offset: 2px;
}

/* A sibling of the list, laid under the button by the controller: inside the
   list it would be clipped by the very `overflow: hidden` that measures the
   trail. Its `left` is written in JavaScript; everything else is here. */
.qc-crumbs__pop {
  position: absolute;
  top: calc(100% + .25rem);
  left: 0;
  z-index: 1030;
  min-width: 10rem;
  max-width: 18rem;
  margin: 0;
  padding: .25rem;
  list-style: none;
  background: var(--qc-surface);
  border: 1px solid var(--qc-border);
  border-radius: var(--qc-radius-btn);
  box-shadow: var(--qc-shadow-md);
  animation: qc-crumbs-pop var(--qc-dur-fast) var(--qc-ease-reveal);
}
.qc-crumbs__pop a {
  display: block;
  padding: .375rem .5rem;
  border-radius: var(--qc-radius-sm);
  color: var(--qc-text-secondary);
  font-size: .8125rem;
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.qc-crumbs__pop a:hover,
.qc-crumbs__pop a:focus-visible {
  background: color-mix(in srgb, var(--qc-primary) 8%, transparent);
  color: var(--qc-text-primary);
}

@keyframes qc-crumbs-pop {
  from { opacity: 0; transform: translateY(-.25rem); }
  to   { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------------------
   The way into the search
   (the panel it opens is public/css/quercia/search.css)
   --------------------------------------------------------------------------- */

.qc-search-trigger {
  display: flex;
  align-items: center;
  gap: .5rem;
  width: 100%;
  height: 2.125rem;
  padding: 0 .625rem;
  border: 1px solid var(--qc-border);
  border-radius: var(--qc-radius-input);
  background: var(--qc-field-bg);
  color: var(--qc-text-tertiary);
  font-size: .8125rem;
  text-align: left;
  cursor: pointer;
  transition: border-color var(--qc-dur-fast) var(--qc-ease-standard),
              color var(--qc-dur-fast) var(--qc-ease-standard);
}
.qc-search-trigger:hover {
  border-color: color-mix(in srgb, var(--qc-primary) 40%, transparent);
  color: var(--qc-text-secondary);
}
.qc-search-trigger:focus-visible {
  outline: 2px solid var(--qc-primary);
  outline-offset: 2px;
}
.qc-search-trigger__label {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.qc-search-trigger__kbd {
  flex: none;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .75rem;
  line-height: 1;
  padding: .1875rem .3125rem;
  border: 1px solid var(--qc-border);
  border-radius: 5px;
  color: var(--qc-text-tertiary);
}

/* ---------------------------------------------------------------------------
   Narrower
   --------------------------------------------------------------------------- */

/* No room for the shortcut, and no keyboard to press it on. */
@media (max-width: 991.98px) {
  .qc-topbar__row { grid-template-columns: minmax(4rem, 1fr) minmax(0, 16rem) minmax(4rem, 1fr); }
  .qc-search-trigger__kbd { display: none; }
}

/* Phone: the arrangement is already right — the actions have their own line at
   every width — so only the field has anything to say here. */
@media (max-width: 575.98px) {
  .qc-topbar__row {
    grid-template-columns: minmax(0, 1fr) auto auto;
    column-gap: .5rem;
  }
  .qc-topbar__search { width: auto; }

  /* The trigger is its icon: the placeholder would not fit beside the trail,
     and the panel it opens carries the field anyway. */
  .qc-search-trigger {
    width: 2.125rem;
    justify-content: center;
    padding: 0;
  }
  .qc-search-trigger__label { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .qc-search-trigger,
  .qc-crumbs__crumb > a,
  .qc-crumbs__ellipsis { transition: none; }
  .qc-crumbs__pop { animation: none; }
}

/* ---------------------------------------------------------------------------
   What is waiting — the bell, the banner, the drawer.

   All three are chrome: the bell stands in the bar on every page, the banner is
   the strip under it, and the drawer covers whatever page it was opened from.
   Nothing here belongs to a feature, which is why it is in this file and not in
   home.css beside the box it shares its rows with.
   --------------------------------------------------------------------------- */

.qc-bell { position: relative; }

/* The number sits on the bell rather than beside it: the corner has room for
   two controls and the count has to survive the phone width, where the person's
   name is already gone.

   Orange and not red — red is the archived badge everywhere else in the
   product, and none of this is dead, it is waiting. The ring is the bar's own
   background, so the badge reads as sitting on the bell at any tint behind it. */
.qc-bell__count {
  position: absolute;
  top: -.3125rem;
  right: -.3125rem;
  min-width: 1.125rem;
  height: 1.125rem;
  padding-inline: .25rem;
  border-radius: var(--qc-radius-pill, 999px);
  background: var(--qc-status-orange);
  color: #3A2200;                       /* on-orange: fixed, and its only use */
  font-size: .6875rem;
  font-weight: 700;
  line-height: 1;
  display: grid;
  place-items: center;
  border: 2px solid var(--qc-card-bg);
  font-variant-numeric: tabular-nums;
}

/* ---- the banner ---- */

/* One `LATE` row, once, across the top. It has no dismiss on purpose — the row
   is derived from the state that caused it and leaves when that is fixed. See
   docs/alerts.md before adding one. */
.qc-alertbanner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .625rem;
  margin-top: .75rem;
  padding: .625rem .875rem;
  border-radius: var(--qc-radius);
  background: color-mix(in srgb, var(--qc-status-orange) 15%, transparent);
  border: 1px solid color-mix(in srgb, var(--qc-status-orange) 40%, transparent);
  font-size: .875rem;
}
.qc-alertbanner__mark {
  color: var(--qc-warning-text);
  flex: none;
  font-size: 1.125rem;
}
.qc-alertbanner__text { flex: 1 1 16rem; min-width: 0; }
.qc-alertbanner__text b { font-weight: 700; }
/* Not `opacity`: the quieter line switches token, so it keeps its contrast. */
.qc-alertbanner__text small {
  display: block;
  color: var(--qc-text-secondary);
  font-size: .8125rem;
  margin-top: .125rem;
}
/* The banner's own buttons stay last on the line at every width. */
.qc-alertbanner > .btn { flex: none; }

/* ---- the drawer ---- */

/* The same panel the help drawer is, because it is the same gesture: something
   slides in from the right over the page you were on and does not take you off
   it. Written out rather than shared with a `.qc-drawer` base — the two have
   different heads, different bodies and different empty states, and a base
   class holding four declarations is a thing to keep in step for no gain. */
.qc-alerts-drawer {
  position: fixed;
  inset: 0;
  z-index: 1055;             /* over the sidebar, under Bootstrap's modals */
}
.qc-alerts-drawer[hidden] { display: none; }

.qc-alerts-drawer__scrim {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--qc-text-primary) 32%, transparent);
  opacity: 0;
  transition: opacity var(--qc-dur-standard) var(--qc-ease-standard);
}
.qc-alerts-drawer.is-open .qc-alerts-drawer__scrim { opacity: 1; }

.qc-alerts-drawer__panel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(26rem, 100vw);
  display: flex;
  flex-direction: column;
  background: var(--qc-card-bg);
  border-left: 1px solid var(--qc-border);
  box-shadow: var(--qc-shadow-lg);
  transform: translateX(100%);
  transition: transform var(--qc-dur-standard) var(--qc-ease-standard);
}
.qc-alerts-drawer.is-open .qc-alerts-drawer__panel { transform: translateX(0); }
.qc-alerts-drawer__panel:focus { outline: none; }

.qc-alerts-drawer__head {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--qc-divider);
}
.qc-alerts-drawer__title {
  font-family: var(--qc-font-display);
  font-size: 1.0625rem;
  font-weight: 700;
  margin: 0;
  flex: 1 1 auto;
}

.qc-alerts-drawer__body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: .5rem 0;
}

/* The page behind the drawer does not scroll under it. */
body.qc-alerts-drawer-open { overflow: hidden; }

/* ---- the rows ---- */

/* Deliberately the attention box's own three columns (home.css): they are the
   same rows, and somebody who has met one on their home has to recognise it
   here. What differs is the padding — this is a full-height panel, not a tile. */
.qc-alerts__list { list-style: none; margin: 0; padding: 0; }
.qc-alerts__row {
  display: grid;
  grid-template-columns: 10px minmax(0, 1fr) auto;
  align-items: start;
  gap: .6875rem;
  padding: .6875rem 1.125rem;
  border-bottom: 1px solid var(--qc-divider);
  color: inherit;
  text-decoration: none;
}
.qc-alerts__row:hover { background: var(--qc-field-bg); color: inherit; }
.qc-alerts__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--sev, var(--qc-text-tertiary));
  margin-top: .3125rem;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--sev, var(--qc-text-tertiary)) 25%, transparent);
}
.qc-alerts__text { font-size: .875rem; line-height: 1.35; color: var(--qc-text-primary); }
.qc-alerts__text b { font-weight: 700; }
.qc-alerts__text small {
  display: block;
  font-size: .75rem;
  color: var(--qc-text-tertiary);
  margin-top: .125rem;
}
/* The right-hand column wraps here, where the home's tile lets it stay on one
   line. The panel is 26rem and the notes are sentences — "scaduta da 33 giorni"
   — so `nowrap` pushes them straight off the edge. A ceiling as well as a wrap,
   or a long one takes the row's whole width from the sentence beside it. */
.qc-alerts__meta {
  font-size: .75rem;
  color: var(--qc-text-tertiary);
  text-align: right;
  max-width: 7.5rem;
  font-variant-numeric: tabular-nums;
  line-height: 1.3;
}
.qc-alerts__meta b {
  display: block;
  font-weight: 700;
  font-size: .8125rem;
  color: var(--qc-text-primary);
}
/* Empty is a good outcome and says so, with the rings — never a panel that
   simply is not there, which teaches people it might not be. */
.qc-alerts__empty {
  display: grid;
  place-items: center;
  text-align: center;
  padding: 2.5rem 1.5rem;
  color: var(--qc-text-secondary);
  font-size: .875rem;
}
.qc-alerts__empty b {
  display: block;
  font-family: var(--qc-font-display);
  font-weight: 700;
  font-size: 1.0625rem;
  color: var(--qc-text-primary);
  margin-top: .375rem;
}

@media (max-width: 575.98px) {
  /* On a phone the panel is the page: a 26rem sheet squeezed into 24rem of
     viewport is a drawer that has forgotten what it is for. */
  .qc-alerts-drawer__panel {
    width: 100vw;
    border-left: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .qc-alerts-drawer__scrim,
  .qc-alerts-drawer__panel { transition: none; }
}
