@scope (.weekly-calendar) {
  :scope {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
  }

  .toolbar {
    display: flex;
    align-items: center;
    gap: var(--space-lg);
    flex-wrap: wrap;
    padding-bottom: var(--space-lg);
    flex-shrink: 0;
  }

  .filters {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
  }

  .week-nav {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
  }

  .nav-icon {
    display: block;
    width: 1.5rem;
    height: 1.5rem;
    flex-shrink: 0;
    fill: currentColor;
  }

  .week-label {
    font-size: var(--text-body);
    font-weight: var(--font-semibold);
    color: var(--color-text-heading);
    min-width: 14ch;
    text-align: center;
  }

  .grid {
    display: grid;
    grid-template-columns: 4rem repeat(7, 1fr);
    /* max-content minimum: hour rows must not shrink below their badges when
       the grid is height-constrained (flex child + overflow). Using
       minmax(3rem, max-content) allowed compression to 3rem, which spilled
       visits into the next hour — worse once the store-color legend appeared
       and stole vertical space from the grid. */
    grid-template-rows: auto repeat(15, max-content);
    align-content: start;
    border: 1px solid var(--color-border-muted);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    overflow: auto;
    background: var(--color-surface);
    flex: 1;
    min-height: 0;
  }

  .corner {
    background: var(--color-surface-muted);
    border-bottom: 1px solid var(--color-border);
    border-right: 1px solid var(--color-border);
  }

  .day-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-2xs);
    padding: var(--space-sm);
    background: var(--color-surface-muted);
    border-bottom: 1px solid var(--color-border);
    border-right: 1px solid var(--color-border-muted);

    &.today {
      background: var(--color-primary);

      .day-name,
      .day-number {
        color: var(--color-text-on-primary);
      }
    }
  }

  .day-name {
    font-size: var(--text-caption);
    font-weight: var(--font-medium);
    color: var(--color-text-secondary);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
  }

  .day-number {
    font-size: var(--text-lg);
    font-weight: var(--font-semibold);
    color: var(--color-text-heading);
    line-height: var(--leading-none);
  }

  .time-label {
    display: flex;
    align-items: flex-start;
    justify-content: flex-end;
    padding: var(--space-2xs) var(--space-sm) 0;
    font-size: var(--text-caption);
    font-weight: var(--font-medium);
    color: var(--color-text-muted);
    border-right: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border-muted);
    background: var(--color-surface);
  }

  .cell {
    /* Column stack: height is the sum of badges, so the hour row grows
       instead of leaking into the slot below. */
    display: flex;
    flex-direction: column;
    align-items: stretch;
    align-content: flex-start;
    gap: var(--space-2xs);
    padding: var(--space-2xs);
    border-right: 1px solid var(--color-border-muted);
    border-bottom: 1px solid var(--color-border-muted);
    min-height: 3rem;
    box-sizing: border-box;

    &.today {
      background: light-dark(
        oklch(97% 0.014 254.604 / 0.3),
        oklch(28.2% 0.091 267.935 / 0.15)
      );
    }
  }

  /* Visit nameplate: closer (or warning) | client. One badge per row in the
     hour cell so several visits grow the slot instead of wrapping sideways. */
  .appointment-badge {
    --_store-stripe: transparent;

    appearance: none;
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    flex: 0 0 auto;
    max-inline-size: 100%;
    min-inline-size: 0;
    padding: var(--space-xs) var(--space-sm);
    border: 0;
    border-radius: var(--radius-full);
    background: var(--color-surface-muted);
    color: var(--color-text);
    font-family: var(--font-body);
    font-size: var(--text-caption);
    font-weight: var(--font-medium);
    line-height: var(--leading-none);
    cursor: pointer;
    text-align: start;

    /* Store accent as an overlay stripe — not box-shadow/border — so colored
       and plain badges keep the same layout size. */
    &::before {
      content: "";
      position: absolute;
      inset-block: 0.2em;
      inset-inline-start: 0;
      inline-size: 3px;
      border-radius: 1px;
      background: var(--_store-stripe);
      pointer-events: none;
    }

    &:focus-visible {
      outline: var(--focus-ring);
      outline-offset: var(--focus-ring-offset);
    }

    @media (hover: hover) {
      &:hover {
        background: var(--color-primary-muted);
      }
    }

    &.appointment-badge--unassigned {
      background: var(--color-warning-muted);
      color: var(--color-warning-text);

      @media (hover: hover) {
        &:hover {
          background: var(--color-warning-muted);
          box-shadow: var(--shadow-xs);
        }
      }

      .appointment-badge__rule {
        background: var(--color-warning-text);
        opacity: 0.35;
      }

      .appointment-badge__client {
        color: var(--color-warning-text);
      }
    }

    &.appointment-badge--inactive {
      opacity: 0.55;
    }

    &.appointment-badge--store-1 { --_store-stripe: var(--color-store-1); }
    &.appointment-badge--store-2 { --_store-stripe: var(--color-store-2); }
    &.appointment-badge--store-3 { --_store-stripe: var(--color-store-3); }
    &.appointment-badge--store-4 { --_store-stripe: var(--color-store-4); }
    &.appointment-badge--store-5 { --_store-stripe: var(--color-store-5); }
    &.appointment-badge--store-6 { --_store-stripe: var(--color-store-6); }
  }

  .appointment-badge__closer,
  .appointment-badge__client {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-inline-size: 0;
  }

  .appointment-badge__closer {
    flex: 0 1 auto;
    font-weight: var(--font-semibold);
    color: var(--color-text-heading);
  }

  .appointment-badge__client {
    flex: 1 1 auto;
    color: var(--color-text-secondary);
  }

  .appointment-badge__rule {
    flex-shrink: 0;
    inline-size: 1px;
    block-size: 0.85em;
    background: var(--color-border);
  }

  .appointment-badge__warning {
    display: inline-flex;
    flex-shrink: 0;
    color: var(--color-warning-text);

    .icon {
      width: 1em;
      height: 1em;
      fill: currentColor;
    }
  }

  .appointment-badge__aware {
    flex-shrink: 0;
    width: var(--space-sm);
    height: var(--space-sm);
    border-radius: var(--radius-full);
    background-color: var(--color-success);
  }

  .appointment-badge__attended {
    flex-shrink: 0;
    width: var(--space-sm);
    height: var(--space-sm);
    border-radius: var(--radius-full);
    background-color: var(--color-info);
  }

  /* Popover: a small card of stacked bands (identity → briefing → ciente →
     actions) separated by hairlines. Fixed measure so long briefing notes
     wrap instead of stretching the card into one unreadable line. */
  .appointment-popover {
    --_pad: var(--space-lg);
    --_notes-max: 10.5rem;

    position: fixed;
    inset: unset;
    position-area: bottom span-right;
    position-try-fallbacks: --above, --left;
    margin: var(--space-xs) 0 0;

    flex-direction: column;
    inline-size: min(23rem, calc(100dvw - 2rem));
    max-block-size: calc(100dvh - 4rem);
    padding: 0;
    overflow: hidden;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface-raised);
    box-shadow: var(--shadow-lg);
    color: var(--color-text);

    /* Only the open state gets a display value: an author-origin `display`
       on the base rule would beat the UA's [popover]:not(:popover-open)
       { display: none } and leave every popover on screen. */
    &:popover-open {
      display: flex;
    }

    &::backdrop {
      background: transparent;
    }

    &.appointment-popover--store-1 { border-inline-start: 3px solid var(--color-store-1); }
    &.appointment-popover--store-2 { border-inline-start: 3px solid var(--color-store-2); }
    &.appointment-popover--store-3 { border-inline-start: 3px solid var(--color-store-3); }
    &.appointment-popover--store-4 { border-inline-start: 3px solid var(--color-store-4); }
    &.appointment-popover--store-5 { border-inline-start: 3px solid var(--color-store-5); }
    &.appointment-popover--store-6 { border-inline-start: 3px solid var(--color-store-6); }
  }

  .store-color-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm) var(--space-md);
    margin-block: var(--space-sm);
    flex-shrink: 0;
    font-size: var(--text-caption);
    color: var(--color-text-secondary);
  }

  .store-color-legend__label {
    font-weight: var(--font-semibold);
    color: var(--color-text);
  }

  .store-color-legend__list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm) var(--space-md);
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .store-color-legend__item {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
  }

  .store-color-legend__swatch {
    inline-size: 0.75rem;
    block-size: 0.75rem;
    border-radius: var(--radius-full);
    background: var(--color-border);
  }

  .store-color-legend__item--store-1 .store-color-legend__swatch { background: var(--color-store-1); }
  .store-color-legend__item--store-2 .store-color-legend__swatch { background: var(--color-store-2); }
  .store-color-legend__item--store-3 .store-color-legend__swatch { background: var(--color-store-3); }
  .store-color-legend__item--store-4 .store-color-legend__swatch { background: var(--color-store-4); }
  .store-color-legend__item--store-5 .store-color-legend__swatch { background: var(--color-store-5); }
  .store-color-legend__item--store-6 .store-color-legend__swatch { background: var(--color-store-6); }

  @position-try --above {
    position-area: top span-right;
    margin: 0 0 var(--space-xs);
  }

  @position-try --left {
    position-area: left span-bottom;
    margin: 0 var(--space-xs) 0 0;
  }

  .popover-header {
    display: flex;
    flex-direction: column;
    gap: var(--space-2xs);
    flex-shrink: 0;
    padding: var(--space-md) var(--_pad);
  }

  .popover-when {
    font-size: var(--text-caption);
    font-weight: var(--font-semibold);
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
  }

  .popover-lead {
    font-size: var(--text-heading-6);
    font-weight: var(--font-semibold);
    line-height: var(--leading-snug);
    color: var(--color-text-heading);
    text-wrap: balance;
  }

  /* Loja / Vendedor / Captador as aligned label–value pairs: the three roles
     the record answers for, in the same order every time. */
  .popover-facts {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    column-gap: var(--space-sm);
    row-gap: var(--space-2xs);
    margin-block-start: var(--space-xs);
    font-size: var(--text-caption);

    dt {
      color: var(--color-text-muted);
      text-transform: uppercase;
      letter-spacing: var(--tracking-wide);
    }

    dd {
      color: var(--color-text-secondary);
      overflow-wrap: anywhere;
    }
  }

  .popover-facts__pending {
    color: var(--color-warning-text);
    font-weight: var(--font-medium);
  }

  .popover-status {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-xs);
    margin-block-start: var(--space-2xs);
  }

  .popover-status__badge {
    padding: 0.125rem var(--space-sm);
    border-radius: var(--radius-full);
    background: var(--color-surface-muted);
    font-size: var(--text-caption);
    font-weight: var(--font-medium);
    color: var(--color-text-muted);
  }

  .popover-status__reason {
    font-size: var(--text-caption);
    color: var(--color-text-muted);
  }

  /* The briefing gets its own tinted band so it reads as quoted material the
     closer has to absorb, not as another field of the record. */
  .popover-notes {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    min-block-size: 0;
    padding: var(--space-md) var(--_pad);
    border-block-start: 1px solid var(--color-border-muted);
    background: var(--color-surface-muted);
  }

  .popover-notes__label {
    font-size: var(--text-caption);
    font-weight: var(--font-semibold);
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
  }

  /* Reading pane: capped height, own scroll, quoted-block rule on the start
     edge. The bottom fade is driven by scroll(self), so it only appears when
     the notes actually overflow — the timeline is inert otherwise. */
  .popover-notes__scroll {
    --_fade: 1.25rem;

    max-block-size: var(--_notes-max);
    overflow-y: auto;
    overscroll-behavior: contain;
    min-block-size: 0;
    scrollbar-width: thin;
    scrollbar-gutter: stable;
    padding-inline: var(--space-md) var(--space-xs);
    padding-block-end: var(--_fade);
    border-inline-start: 2px solid var(--color-border);

    &:focus-visible {
      outline: var(--focus-ring);
      outline-offset: var(--focus-ring-offset);
    }

    @supports (animation-timeline: scroll(self)) {
      animation: appointment-notes-overflow linear both;
      animation-timeline: scroll(self);
    }
  }

  .popover-notes__text {
    font-size: var(--text-body-sm);
    line-height: var(--leading-relaxed);
    color: var(--color-text-secondary);
    overflow-wrap: anywhere;

    p + p {
      margin-block-start: var(--space-sm);
    }
  }

  .popover-notes__empty {
    font-size: var(--text-body-sm);
    font-style: italic;
    color: var(--color-text-muted);
  }

  /* "Ciente" sits right below the briefing: you read, then you acknowledge.
     It is an action, not a form field — a toggle button with a drawn box. */
  .popover-aware {
    flex-shrink: 0;
    border-block-start: 1px solid var(--color-border-muted);

    /* button_to renders a <form><button> — let the button be the row */
    .aware-toggle__form {
      display: contents;
    }
  }

  .popover-attendance {
    flex-shrink: 0;
    border-block-start: 1px solid var(--color-border-muted);

    .aware-toggle__form {
      display: contents;
    }
  }

  .popover-negotiation {
    flex-shrink: 0;
    padding: var(--space-sm) var(--_pad);
    border-block-start: 1px solid var(--color-border-muted);
  }

  .popover-negotiation__label {
    margin: 0 0 var(--space-xs);
    font-size: var(--text-caption);
    font-weight: var(--font-semibold);
    color: var(--color-text-muted);
  }

  .aware-toggle {
    all: unset;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    inline-size: 100%;
    padding: var(--space-md) var(--_pad);
    font-family: var(--font-body);
    font-size: var(--text-body-sm);
    font-weight: var(--font-medium);
    color: var(--color-text);
    cursor: pointer;
    transition: background-color 0.18s ease, color 0.18s ease;

    &:hover {
      background: var(--color-surface-muted);
    }

    &:focus-visible {
      outline: var(--focus-ring);
      outline-offset: calc(var(--focus-ring-offset) * -1);
    }

    &[aria-pressed="true"] {
      background: var(--color-success-muted);
      color: var(--color-success-text);

      .aware-toggle__box {
        background: var(--color-success);
        border-color: var(--color-success);
        color: var(--white);
      }

      .icon {
        opacity: 1;
      }
    }
  }

  .aware-toggle__box {
    display: grid;
    place-items: center;
    inline-size: 1.125rem;
    block-size: 1.125rem;
    flex-shrink: 0;
    border: 1.5px solid var(--color-text-muted);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    transition: background-color 0.18s ease, border-color 0.18s ease;

    .icon {
      inline-size: 0.875rem;
      block-size: 0.875rem;
      fill: currentColor;
      opacity: 0;
    }
  }

  .aware-toggle__meta {
    margin-inline-start: auto;
    font-size: var(--text-caption);
    font-weight: var(--font-normal);
    color: var(--color-text-muted);
    text-align: end;
  }

  .popover-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    flex-shrink: 0;
    gap: var(--space-xs);
    padding: var(--space-sm) var(--space-md);
    border-block-start: 1px solid var(--color-border-muted);
    background: var(--color-surface-muted);

    /* Footer scale: the popover is 23rem wide, full-height buttons crowd it */
    .button {
      --_height: 2rem;
      --_padding-x: var(--space-md);
      --_size: var(--text-body-sm);
      --_radius: var(--radius-md);
    }

    .popover-actions__end {
      margin-inline-start: auto;
    }
  }

  .appointment-count {
    color: var(--color-text-muted);
    margin-inline-start: auto;
    white-space: nowrap;
  }

  @media (width < 48rem) {
    .grid {
      overflow-x: auto;
      min-width: 600px;
    }

    .toolbar {
      flex-direction: column;
      align-items: stretch;
    }

    .week-nav {
      justify-content: center;
    }

    .appointment-count {
      margin-inline-start: 0;
      text-align: center;
    }
  }

  /* Short viewports: keep the actions reachable by shrinking the reading pane */
  @media (height < 44rem) {
    .appointment-popover {
      --_notes-max: 6.5rem;
    }
  }
}

/* Static edge fade for the briefing pane. Same value at both ends, so nothing
   moves: the animation exists only so scroll(self) can gate it on overflow. */
@keyframes appointment-notes-overflow {
  from,
  to {
    mask-image: linear-gradient(
      to bottom,
      #000 0,
      #000 calc(100% - var(--_fade)),
      transparent 100%
    );
  }
}
