/*
  header-actions.css — the language switcher and the way in, dressed in tokens.

  ── Why tokens and not the colours that were here ────────────────────────────
  This markup used to live inside the core's default layout with `#1e293b`,
  `#334155` and `#6366f1` written into site.css. The moment it becomes a shared
  piece, those literals become a navy slab on a black site — the exact defect
  the consent banner had until yesterday, in a different file. Every colour below
  falls back to the value the core shipped, so a theme that declares nothing does
  not move a pixel; a theme with a palette maps a dozen variables and the whole
  piece follows.

  ── What was missing entirely ────────────────────────────────────────────────
  `.lang-drop` had NO base rules in the core: three size tweaks under a media
  query and nothing else. The public language switcher was an unstyled native
  <details>, so its options rendered in flow and shoved the header aside when
  opened. The panel below is what should always have been there.

  Sizes are the accessible ones, not the pretty ones: 44px of touch target
  (WCAG 2.5.5), which is also what the consent banner uses.
*/

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--ha-gap, .5rem);
}

/* ── shared dropdown shell ─────────────────────────────────────────────────── */

.ha-menu { position: relative; display: inline-flex; }

/*
  `hidden` is a display of `none` from the BROWSER's stylesheet, so any author
  rule that sets `display` — the line above — wins and the element shows anyway.
  Without this, the front bell rendered for every visitor, including the ones
  with no notifications at all: an icon that opens an empty box, which is exactly
  what the decision behind it set out to avoid. Measured on production the day
  after it shipped.

  `pwa-install.css` has carried the same guard since the day it was written; this
  sheet is the second screen where the canon was not applied. Enumerated now by
  FactoryPartialHiddenTest, so a third one cannot happen quietly.
*/
.ha-menu[hidden] { display: none; }

/*
  Where each control lives, per breakpoint — the theme decides, the core only
  provides the two classes (see the partial's `lang_class` / `signin_class` /
  `theme_toggle_class`).

  Why it is needed: a header row holds the logo and roughly three 44px controls.
  The vertical's row had four plus a wordmark and the logo slid UNDER the globe —
  flex shrank its box (`min-width: 0`) and the text kept painting. Nothing
  overflowed and nothing was clipped, so neither the suite nor the mobile bench
  could see it; Adán sent a photograph. The bench now measures overlap too.

  `--wide` is the pattern the theme toggle already used (`ha-theme--wide`); this
  generalises it instead of adding a second spelling of the same idea.

  ⚠️ These classes HIDE a control below or above a width, so reach for them only
  when the control has somewhere else to be. Hiding the language switcher and
  the way in behind a drawer was tried first and was the wrong answer: what a
  visitor could see must stay visible, and the fix belongs in the LAYOUT — the
  vertical now carries a two-row header (utilities above, identity below), which
  the four `show_*` switches make possible without hiding anything.
*/
@media (max-width: 480px) {
  .ha-only-wide { display: none !important; }
}
@media (min-width: 481px) {
  .ha-only-narrow { display: none !important; }
}

.ha-menu > summary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .35rem;
  min-height: 44px;
  min-width: 44px;
  padding: 0 .5rem;
  border-radius: var(--ha-radius, .4rem);
  color: var(--ha-ink, currentColor);
  cursor: pointer;
  user-select: none;
  list-style: none;                       /* Firefox */
}
.ha-menu > summary::-webkit-details-marker { display: none; }
.ha-menu > summary::marker { content: ''; }
.ha-menu > summary:hover { background: var(--ha-trigger-hover, rgba(255, 255, 255, .08)); }
/* Keyboard users must see where they are; `outline: none` here would be the
   classic accessibility regression that no screenshot shows. */
.ha-menu > summary:focus-visible {
  outline: 2px solid var(--ha-focus, currentColor);
  outline-offset: 2px;
}

.ha-menu__panel {
  position: absolute;
  right: 0;
  top: calc(100% + .45rem);
  min-width: 190px;
  padding: .3rem;
  background: var(--ha-surface, #1e293b);
  border: 1px solid var(--ha-border, #334155);
  border-radius: var(--ha-radius, .4rem);
  box-shadow: var(--ha-shadow, 0 8px 24px rgba(0, 0, 0, .35));
  z-index: var(--ha-z, 50);
}

.ha-menu__panel a,
.ha-menu__panel button {
  display: flex;
  align-items: center;
  gap: .5rem;
  width: 100%;
  min-height: 40px;
  padding: .5rem .6rem;
  border: 0;
  border-radius: .25rem;
  background: none;
  color: var(--ha-menu-ink, #cbd5e1);
  font: inherit;
  font-size: .85rem;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.ha-menu__panel a:hover,
.ha-menu__panel button:hover {
  color: var(--ha-menu-ink-hover, #fff);
  background: var(--ha-menu-hover, #334155);
}
.ha-menu__panel a.is-active {
  color: var(--ha-menu-ink-hover, #fff);
  font-weight: 600;
}

.ha-menu__chev {
  width: 11px;
  height: 11px;
  flex-shrink: 0;
  opacity: .8;
  transition: transform .15s ease;
}
.ha-menu[open] .ha-menu__chev { transform: rotate(180deg); }

/* ── language ─────────────────────────────────────────────────────────────── */

.ha-lang__globe { width: 18px; height: 18px; flex-shrink: 0; }

/*
  ── The four widths of the cluster, declared in ONE place ────────────────────
  This is the ladder the whole cluster obeys, and it is the core's: a theme
  chooses where the cluster sits and what colour it is, never how it behaves at
  a width (contrato-base §14). Written here rather than in a theme is the whole
  correction of 2026-08-16.

  | width          | what is shown                                  |
  |----------------|------------------------------------------------|
  | < 768  phone   | icons only                                     |
  | 768–1023 tablet| icons only    ← the rung that did not exist     |
  | 1024–1279 desk | + the sign-in label, + the language ISO code    |
  | ≥ 1280   wide  | + the language name in full, instead of the code|

  FOUR and not three because the range that broke is exactly the one that was
  missing: `.ha-signin__label` and `.ha-lang__code` were only withdrawn below
  768, so between 768 and 1024 both showed next to six nav links. Measured on
  `core.onlainez.net/es/` at 768px: the nav needed 465px in a 416px row, wrapped
  onto two lines, and "Iniciar sesión" broke in half. In English it fit, which is
  why testing in one language never saw it.

  Icons only, and it is Adán's call, made with the reason a shop makes it: the
  room this frees is where the basket, the search and the wishlist go (Shopify,
  Zalando, Amazon). The accessible name stays on every control, so nothing is
  lost to a screen reader — what changes is that the word is not painted.

  The language keeps its three-step scale (patrones/selector-idioma.md): name →
  ISO code → globe alone. It is CSS, never a user setting — "how to show the
  option" is not a preference anyone should have to configure.
*/
.ha-lang__name { white-space: nowrap; }
.ha-lang__code { display: none; text-transform: uppercase; font-size: .8rem; letter-spacing: .02em; }

/* Below the widest rung: the full name gives way to the code. */
@media (max-width: 1279px) {
  .ha-lang__name { display: none; }
  .ha-lang__code { display: inline; }
}
/* Below the desktop rung: icons only — no code, no sign-in label. */
@media (max-width: 1023px) {
  .ha-lang__code { display: none; }
}
@media (max-width: 767px) {
  .ha-lang__globe { width: 22px; height: 22px; }   /* level with a 24px hamburger */
  /* Globe alone, no caret: the canon's third step. Measured on a 393px phone,
     the caret plus its gap was 11px of a row that was already 5px too wide —
     the whole cluster shares the line with a logo and a hamburger. Tapping the
     globe still opens the panel; the caret was decoration. */
  .ha-lang > summary .ha-menu__chev { display: none; }
  .ha-lang > summary { padding: 0 .25rem; }
  .header-actions { --ha-gap: .15rem; }
}

/* ── the way in ───────────────────────────────────────────────────────────── */

.ha-signin {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  min-height: 44px;
  min-width: 44px;
  padding: 0 .6rem;
  border-radius: var(--ha-radius, .4rem);
  color: var(--ha-ink, currentColor);
  text-decoration: none;
}
.ha-signin:hover { background: var(--ha-trigger-hover, rgba(255, 255, 255, .08)); }
.ha-signin:focus-visible { outline: 2px solid var(--ha-focus, currentColor); outline-offset: 2px; }
.ha-signin svg { width: 20px; height: 20px; flex-shrink: 0; }
/* The word is for people who are looking for it; below a desktop the icon
   carries it, and the accessible name stays on the link either way. 1024 and
   not 768: see the ladder above — on a tablet this label plus the language code
   plus six nav links is what pushed the row onto two lines. */
@media (max-width: 1023px) { .ha-signin__label { display: none; } }

.ha-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--ha-avatar-bg, #6366f1);
  color: var(--ha-avatar-ink, #fff);
  font-size: .8rem;
  font-weight: 700;
  text-transform: uppercase;
}

.ha-menu__who {
  display: block;
  padding: .35rem .6rem .5rem;
  margin-bottom: .25rem;
  border-bottom: 1px solid var(--ha-border, #334155);
  color: var(--ha-menu-muted, #94a3b8);
  font-size: .75rem;
  white-space: nowrap;
}
.ha-menu__panel form { margin: 0; }
.ha-menu__panel form button svg { width: 16px; height: 16px; }

/* ── light / dark ─────────────────────────────────────────────────────────── */

/*
  The control that used to cost a band of screen. In the vertical it sat in a
  strip of its own above the nav; once the language pills moved into the cluster
  that strip was left holding one button and a whole row of a phone's height.
  Here it is one more 44px target at the quiet end of the cluster.

  `.ha-theme--wide` is for a theme that ALSO puts one inside its drawer: it hides
  this copy on a phone so the row does not grow. Both stay in sync — the script
  works by attribute, not by id.
*/
/* `hidden` gana: medido en Chrome, 44x44 px con el atributo puesto. */
.ha-theme[hidden] { display: none; }

.ha-theme {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
  padding: 0 .35rem;
  border: 0;
  border-radius: var(--ha-radius, .4rem);
  background: none;
  color: var(--ha-ink, currentColor);
  cursor: pointer;
}
.ha-theme:hover { background: var(--ha-trigger-hover, rgba(255, 255, 255, .08)); }
.ha-theme:focus-visible { outline: 2px solid var(--ha-focus, currentColor); outline-offset: 2px; }
.ha-theme svg { width: 20px; height: 20px; flex-shrink: 0; }

/* Show the icon of what the button DOES, not of where you are: on a dark site it
   offers the sun. Same reading as the accessible name, which states the action. */
.ha-theme__sun  { display: inline; }
.ha-theme__moon { display: none; }
[data-theme="light"] .ha-theme__sun  { display: none; }
[data-theme="light"] .ha-theme__moon { display: inline; }

@media (max-width: 767px) {
  .ha-theme--wide { display: none; }
  .ha-theme { padding: 0 .25rem; }
}

/* ── The public bell (migration 1059) ────────────────────────────────────────
   Drawn only for somebody who has actually been notified, so these rules are
   dead weight on most sites — which is why they live here, with the rest of the
   cluster, instead of in a sheet of their own that every page would fetch. */
.ha-bell > summary {
  position: relative;
  min-height: 44px;
  min-width: 44px;
  padding: 0 .35rem;
}
.ha-bell > summary svg { width: 20px; height: 20px; flex-shrink: 0; }

/* The badge sits on the icon, not next to it: the cluster must not reflow when
   a notice arrives and the count appears. */
.ha-bell__badge {
  position: absolute;
  top: 6px;
  right: 2px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--ha-badge-bg, #dc2626);
  color: var(--ha-badge-ink, #fff);
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}

.ha-bell__panel {
  width: min(340px, calc(100vw - 2rem));
  max-height: min(60vh, 420px);
  /* The panel is a column and the SCROLL belongs to the list: a header that
     scrolls away takes "mark all read" with it exactly when a long tray is the
     reason somebody wants it. Canon: GitHub, Slack, Linear. */
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0;
}

.ha-bell__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  flex-shrink: 0;
  padding: .6rem .75rem .6rem 1rem;
  border-bottom: 1px solid var(--ha-border, rgba(255, 255, 255, .12));
}

.ha-bell__title {
  font-size: .8125rem;
  font-weight: 600;
  opacity: .85;
  flex-shrink: 0;
}

/* `.ha-menu__panel button` above makes every button in a panel a full-width row.
   This one is a control inside a header, so it takes its size back. */
.ha-bell__clear {
  width: auto;
  display: inline-flex;
  padding: .25rem .4rem;
  font-size: .75rem;
  background: none;
  border: 0;
  color: inherit;
  opacity: .7;
  cursor: pointer;
  border-radius: var(--ha-radius, .4rem);
  /* Measured at 375px against production: the German label is 245px of the
     357px row. It fits, and it is allowed to shrink — but if it ever does, the
     text stays against the right edge instead of leaving a gap there. */
  text-align: right;
}
.ha-bell__clear:hover,
.ha-bell__clear:focus-visible { opacity: 1; background: var(--ha-item-hover, rgba(255, 255, 255, .06)); }
/* Without this the button shows while the tray is empty: `hidden` is the
   browser sheet's display:none and the rule above declares one. */
.ha-bell__clear[hidden] { display: none; }

.ha-bell__list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

.ha-bell__foot {
  flex-shrink: 0;
  margin: 0;
  padding: .5rem 1rem .6rem;
  font-size: .6875rem;
  opacity: .6;
  border-top: 1px solid var(--ha-border, rgba(255, 255, 255, .12));
}
.ha-bell__foot[hidden] { display: none; }

/*
  On a narrow phone the panel is wider than the space left of its trigger, and
  `right: 0` anchors it to the BUTTON, not to the screen — so 340px hanging off
  an icon that sits in the middle of the cluster runs off the left edge (95px at
  375px wide, measured). The other menus are 190px and fit; only this one does
  not, so only this one changes.

  The fix is the phone pattern itself (GitHub, Slack, Linear): stop hanging the
  notification list off the button and pin it to the viewport with a margin each
  side. Above 480px nothing changes.
*/
/*
  On a narrow phone the panel is wider than the space left of its trigger, and
  the shared dropdown anchors to the BUTTON (`.ha-menu { position: relative }`),
  so 340px hanging off an icon in the middle of the cluster runs off the screen —
  96px at 393px wide, measured against the live site.

  The fix anchors it to the CLUSTER instead, which reaches the right edge of the
  screen: the bell stops being a positioning context on a phone and the panel
  hangs off `.header-actions`. `position: fixed` was tried first and does NOT
  work here — an ancestor in the vertical's sticky nav establishes a containing
  block (backdrop-filter does that), so the "fixed" panel stayed anchored to the
  button and the width change alone pushed it 283px off. Measured, not reasoned:
  the bench reported left=315 with the box 361 wide.

  Only the bell: the other menus are 190px and fit where they are.
*/
@media (max-width: 480px) {
  .header-actions { position: relative; }
  /* Two classes on purpose: `.ha-bell` alone TIES with `.ha-menu { position:
     relative }` and the later rule wins by accident of file order — measured,
     the panel stayed anchored to the button (right edge at 315px on a 375px
     screen, 25px of it off the left edge). Specificity here is not decoration. */
  .header-actions .ha-bell { position: static; }
  /*
    Pinned to the screen, not hung off the cluster. Anchoring to the cluster was
    not enough: the strip carries a generous side padding, so its right edge sits
    60px in and a 340px panel still ran 25px off the left — measured, right edge
    at 315 on a 375px screen.

    `position: fixed` works here and did not before: it is neutered by an
    ancestor with `backdrop-filter` (the vertical's sticky nav has one), and the
    bell no longer lives there. `--ha-bell-panel-top` is how a theme says how far
    down its own header ends; the fallback matches the core's 64px nav.
  */
  .ha-bell__panel {
    position: fixed;
    left: .5rem;
    right: .5rem;
    top: var(--ha-bell-panel-top, 4.25rem);
    width: auto;
    min-width: 0;
    max-height: min(70vh, 480px);
  }
}
.ha-bell__empty {
  padding: 1rem;
  font-size: .875rem;
  opacity: .7;
  text-align: center;
}

/* The rows come from notif-render.js, shared with the panel. Only the public
   dressing lives here — the structure is one implementation. */
.ha-bell__panel .notif-item {
  display: flex;
  gap: .75rem;
  align-items: flex-start;
  padding: .75rem 1rem;
  border-bottom: 1px solid var(--ha-border, rgba(255, 255, 255, .12));
  text-decoration: none;
  color: inherit;
}
.ha-bell__panel .notif-item:last-child { border-bottom: 0; }
.ha-bell__panel .notif-item:hover { background: var(--ha-item-hover, rgba(255, 255, 255, .06)); }
/* Read, not gone: this tray is the visitor's only copy. */
.ha-bell__panel .notif-item.is-read { opacity: .6; }
.ha-bell__panel .notif-item__icon {
  width: 28px; height: 28px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: color-mix(in srgb, currentColor 12%, transparent);
}
.ha-bell__panel .notif-item__icon svg {
  width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2;
}
.ha-bell__panel .notif-item__body  { flex: 1; min-width: 0; }
.ha-bell__panel .notif-item__title { font-size: .875rem; font-weight: 600; }
.ha-bell__panel .notif-item__sub   { font-size: .75rem; opacity: .75; margin-top: 2px; }
.ha-bell__panel .notif-item__time  { font-size: .6875rem; opacity: .6; white-space: nowrap; }
