/* ==========================================================================
   NOTIFICATIONS

   The bell and its dropdown, the permission invitation, the notification
   centre list, the order tracking timeline, and the back-office notification
   screens.

   Shared by the shop and the back office, because both have a bell and both
   show the same kind of list. Uses the tokens already defined in site.css -
   no new colours are invented here.
   ========================================================================== */

/* -- Bell ---------------------------------------------------------------- */

.tx-bell { position: relative; }

.tx-bell__btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: 0;
    background: transparent;
    color: inherit;
    border-radius: var(--tx-radius-pill);
    cursor: pointer;
    transition: background var(--tx-fast) var(--tx-ease);
}

.tx-bell__btn:hover { background: rgba(0, 0, 0, .06); }
.tx-bell__btn:focus-visible { outline: 2px solid var(--tx-gold); outline-offset: 2px; }

/* The count sits on the bell rather than beside it, so the header does not
   reflow every time something arrives. */
.tx-bell__count {
    position: absolute;
    top: 3px;
    right: 2px;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: var(--tx-radius-pill);
    background: var(--tx-fail);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 17px;
    text-align: center;
    box-shadow: 0 0 0 2px var(--tx-white);
}

.tx-bell__count[hidden] { display: none; }

/* A short pulse when the count changes: enough to catch the eye, not enough to
   be a distraction on a page somebody is working in. */
.tx-bell__count.is-new { animation: tx-bell-pop 520ms var(--tx-ease); }

@keyframes tx-bell-pop {
    0%   { transform: scale(1); }
    35%  { transform: scale(1.45); }
    100% { transform: scale(1); }
}

.tx-bell__btn.is-ringing svg {
    animation: tx-bell-ring 700ms var(--tx-ease);
    transform-origin: top center;
}

@keyframes tx-bell-ring {
    0%, 100% { transform: rotate(0); }
    20% { transform: rotate(12deg); }
    40% { transform: rotate(-10deg); }
    60% { transform: rotate(6deg); }
    80% { transform: rotate(-4deg); }
}

.tx-bell__panel {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    width: min(380px, calc(100vw - 32px));
    max-height: min(520px, 70vh);
    display: flex;
    flex-direction: column;
    background: var(--tx-white);
    border: 1px solid var(--tx-line);
    border-radius: var(--tx-radius);
    box-shadow: var(--tx-shadow-lg);
    z-index: 60;
    overflow: hidden;

    opacity: 0;
    transform: translateY(-6px) scale(.98);
    pointer-events: none;
    transition: opacity var(--tx-fast) var(--tx-ease), transform var(--tx-fast) var(--tx-ease);
}

.tx-bell__panel.is-open { opacity: 1; transform: none; pointer-events: auto; }

.tx-bell__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--tx-gap-sm);
    padding: 12px 14px;
    border-bottom: 1px solid var(--tx-line-soft);
}

.tx-bell__head h4 { margin: 0; font-size: 14px; font-weight: 700; color: var(--tx-ink); }

.tx-bell__list { overflow-y: auto; flex: 1 1 auto; }

.tx-bell__item {
    display: block;
    padding: 12px 14px;
    border-bottom: 1px solid var(--tx-line-soft);
    color: inherit;
    text-decoration: none;
    transition: background var(--tx-fast) var(--tx-ease);
}

.tx-bell__item:hover { background: var(--tx-cream); }
.tx-bell__item:last-child { border-bottom: 0; }

/* Unread gets a rail rather than a heavy fill, so a long list of unread items
   does not turn into a wall of colour. */
.tx-bell__item.is-unread {
    background: var(--tx-wine-soft);
    box-shadow: inset 3px 0 0 var(--tx-wine);
}

.tx-bell__title { display: block; font-weight: 600; font-size: 13px; color: var(--tx-ink); }
.tx-bell__text  { display: block; font-size: 12.5px; color: var(--tx-body); margin-top: 2px; }
.tx-bell__meta  { display: block; font-size: 11px; color: var(--tx-muted); margin-top: 4px; }

.tx-bell__foot {
    padding: 10px 14px;
    border-top: 1px solid var(--tx-line-soft);
    background: var(--tx-cream);
    text-align: center;
}

.tx-bell__empty { padding: 32px 16px; text-align: center; color: var(--tx-muted); font-size: 13px; }

/* Placeholder rows while the first fetch is in flight, so the panel does not
   open empty and then jump. */
.tx-bell__skel { padding: 12px 14px; border-bottom: 1px solid var(--tx-line-soft); }

.tx-bell__skel span {
    display: block;
    height: 10px;
    border-radius: 4px;
    margin-bottom: 6px;
    background: linear-gradient(90deg, var(--tx-line-soft) 25%, var(--tx-line) 37%, var(--tx-line-soft) 63%);
    background-size: 400% 100%;
    animation: tx-skel-slide 1.3s ease-in-out infinite;
}

.tx-bell__skel span:first-child { width: 55%; }
.tx-bell__skel span:last-child  { width: 85%; margin-bottom: 0; }

@keyframes tx-skel-slide {
    from { background-position: 100% 50%; }
    to   { background-position: 0 50%; }
}

/* -- Permission invitation ----------------------------------------------- */

/* Our own panel, shown before the browser's prompt. Firing the real permission
   dialog unannounced is how sites get permanently blocked: a browser only asks
   once, and "Block" cannot be undone from the page. */
.tx-pushask {
    position: fixed;
    left: 16px;
    bottom: 16px;
    width: min(360px, calc(100vw - 32px));
    padding: 16px;
    background: var(--tx-white);
    border: 1px solid var(--tx-line);
    border-radius: var(--tx-radius);
    box-shadow: var(--tx-shadow-lg);
    z-index: 80;

    opacity: 0;
    transform: translateY(14px);
    transition: opacity var(--tx-normal) var(--tx-ease), transform var(--tx-normal) var(--tx-ease);
}

.tx-pushask.is-open { opacity: 1; transform: none; }

.tx-pushask h4 { margin: 0 0 6px; font-size: 15px; color: var(--tx-ink); }
.tx-pushask p  { margin: 0 0 12px; font-size: 13px; color: var(--tx-body); line-height: 1.5; }
.tx-pushask__actions { display: flex; gap: var(--tx-gap-sm); }

/* -- Notification centre -------------------------------------------------- */

.tx-notif__day {
    margin: var(--tx-gap-md) 0 var(--tx-gap-sm);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--tx-muted);
}

.tx-notif__day:first-child { margin-top: 0; }

.tx-notif__item {
    display: flex;
    gap: var(--tx-gap);
    align-items: flex-start;
    padding: 14px;
    background: var(--tx-white);
    border: 1px solid var(--tx-line);
    border-radius: var(--tx-radius);
    margin-bottom: var(--tx-gap-sm);
    color: inherit;
    text-decoration: none;
    transition: transform var(--tx-fast) var(--tx-ease), box-shadow var(--tx-fast) var(--tx-ease);
}

.tx-notif__item:hover { transform: translateY(-1px); box-shadow: var(--tx-shadow-sm); }
.tx-notif__item.is-unread { border-left: 3px solid var(--tx-wine); background: var(--tx-wine-soft); }

.tx-notif__icon {
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    border-radius: var(--tx-radius-pill);
    background: var(--tx-cream);
    color: var(--tx-wine);
    font-size: 13px;
    font-weight: 700;
}

.tx-notif__body { flex: 1 1 auto; min-width: 0; }
.tx-notif__body h4 { margin: 0 0 3px; font-size: 14px; color: var(--tx-ink); }
.tx-notif__body p  { margin: 0; font-size: 13px; color: var(--tx-body); line-height: 1.5; white-space: pre-line; }
.tx-notif__when { font-size: 11.5px; color: var(--tx-muted); white-space: nowrap; }

/* -- Order tracking timeline --------------------------------------------- */

.tx-track { padding: var(--tx-gap-sm) 0; }

.tx-track__rail {
    position: relative;
    display: flex;
    justify-content: space-between;
    gap: var(--tx-gap-xs);
    margin: var(--tx-gap) 0 var(--tx-gap-md);
}

/* The grey track and the coloured fill are two pseudo-elements on the wrapper
   rather than borders on each step, so progress animates as one continuous
   line instead of several separate ones. */
.tx-track__rail::before,
.tx-track__rail::after {
    content: "";
    position: absolute;
    top: 13px;
    left: 6%;
    right: 6%;
    height: 3px;
    border-radius: 2px;
}

.tx-track__rail::before { background: var(--tx-line); }

.tx-track__rail::after {
    right: auto;
    width: calc(88% * var(--tx-progress, 0) / 100);
    background: linear-gradient(90deg, var(--tx-wine), var(--tx-gold));
    transition: width var(--tx-slow) var(--tx-ease);
}

.tx-track__step {
    position: relative;
    z-index: 1;
    flex: 1 1 0;
    min-width: 0;
    text-align: center;
}

.tx-track__dot {
    width: 28px;
    height: 28px;
    margin: 0 auto 8px;
    display: grid;
    place-items: center;
    border-radius: var(--tx-radius-pill);
    background: var(--tx-white);
    border: 3px solid var(--tx-line);
    color: var(--tx-muted);
    font-size: 12px;
    font-weight: 700;
    transition: border-color var(--tx-normal) var(--tx-ease),
                background var(--tx-normal) var(--tx-ease),
                color var(--tx-normal) var(--tx-ease);
}

.tx-track__step.is-done .tx-track__dot {
    background: var(--tx-wine);
    border-color: var(--tx-wine);
    color: #fff;
}

.tx-track__step.is-current .tx-track__dot {
    background: var(--tx-gold);
    border-color: var(--tx-gold);
    color: #fff;
    animation: tx-track-pulse 2s var(--tx-ease) infinite;
}

@keyframes tx-track-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(184, 135, 58, .5); }
    70%  { box-shadow: 0 0 0 12px rgba(184, 135, 58, 0); }
    100% { box-shadow: 0 0 0 0 rgba(184, 135, 58, 0); }
}

.tx-track__name {
    display: block;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--tx-muted);
    line-height: 1.3;
}

.tx-track__step.is-done .tx-track__name,
.tx-track__step.is-current .tx-track__name { color: var(--tx-ink); }

.tx-track__when { display: block; font-size: 10.5px; color: var(--tx-muted); margin-top: 3px; }

.tx-track__courier {
    display: flex;
    flex-wrap: wrap;
    gap: var(--tx-gap-md);
    align-items: center;
    justify-content: space-between;
    padding: var(--tx-gap);
    background: var(--tx-cream);
    border: 1px solid var(--tx-line);
    border-radius: var(--tx-radius);
}

.tx-track__courier dl { margin: 0; display: flex; flex-wrap: wrap; gap: var(--tx-gap-md); }
.tx-track__courier div { min-width: 0; }
.tx-track__courier dt { font-size: 11px; color: var(--tx-muted); }
.tx-track__courier dd { margin: 0; font-size: 13px; font-weight: 600; color: var(--tx-ink); }

/* Below roughly 640px a horizontal rail stops being readable - six labels in
   320px is unusable - so it becomes a vertical list. */
@media (max-width: 640px) {
    .tx-track__rail { flex-direction: column; gap: 0; }

    .tx-track__rail::before {
        top: 14px; bottom: 14px; left: 13px; right: auto;
        width: 3px; height: auto;
    }

    .tx-track__rail::after {
        top: 14px; left: 13px; right: auto; width: 3px;
        height: calc((100% - 28px) * var(--tx-progress, 0) / 100);
        background: linear-gradient(180deg, var(--tx-wine), var(--tx-gold));
        transition: height var(--tx-slow) var(--tx-ease);
    }

    .tx-track__step {
        display: flex;
        align-items: flex-start;
        gap: var(--tx-gap);
        text-align: left;
        padding-bottom: 14px;
    }

    .tx-track__dot { margin: 0; flex: 0 0 auto; }
    .tx-track__name { font-size: 13px; }
}

/* -- Back office: event configuration grid -------------------------------- */

.tx-eventgrid { width: 100%; border-collapse: collapse; }

.tx-eventgrid th,
.tx-eventgrid td {
    padding: 10px 8px;
    border-bottom: 1px solid var(--tx-line-soft);
    font-size: 13px;
    text-align: center;
    vertical-align: middle;
}

.tx-eventgrid th { font-size: 11px; color: var(--tx-muted); font-weight: 700; }
.tx-eventgrid td:first-child,
.tx-eventgrid th:first-child { text-align: left; }

.tx-eventgrid tbody tr:hover { background: var(--tx-cream); }

/* Customer and owner columns are visually paired so the grid reads as three
   channels of two rather than six unrelated columns. */
.tx-eventgrid .tx-eventgrid__pair { border-left: 1px solid var(--tx-line); }

.tx-eventgrid__group {
    background: var(--tx-cream);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--tx-muted);
}

.tx-eventgrid__group td { text-align: left; padding: 8px 10px; }

.tx-eventgrid input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; accent-color: var(--tx-wine); }
.tx-eventgrid input[type="checkbox"]:disabled { cursor: not-allowed; opacity: .35; }

.tx-eventname { font-weight: 600; color: var(--tx-ink); }
.tx-eventname small { display: block; font-weight: 400; color: var(--tx-muted); font-size: 11.5px; margin-top: 2px; }

/* -- Back office: log payload -------------------------------------------- */

.tx-payload {
    margin: 0;
    padding: var(--tx-gap);
    background: var(--tx-ink);
    color: #e9e4e0;
    border-radius: var(--tx-radius);
    font-family: Consolas, "SF Mono", Menlo, monospace;
    font-size: 12px;
    line-height: 1.55;
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 380px;
    overflow: auto;
}

.tx-msgpreview {
    margin: 0;
    padding: var(--tx-gap);
    background: #e8f5e4;
    border: 1px solid #cfe6c8;
    border-radius: var(--tx-radius);
    font-family: var(--tx-font-body);
    font-size: 13px;
    line-height: 1.6;
    white-space: pre-wrap;
    word-break: break-word;
}

@media (prefers-reduced-motion: reduce) {
    .tx-track__step.is-current .tx-track__dot,
    .tx-bell__count.is-new,
    .tx-bell__skel span,
    .tx-bell__btn.is-ringing svg { animation: none; }
}

/* -- Narrow-screen spec tables -------------------------------------------- */

/* A table will not shrink below its own content, whatever min-width the cell
   around it is given - table layout is content-driven. On a phone that means a
   two-column label/value table quietly pushes the whole page sideways.

   Stacking label above value fixes the overflow and reads better on a narrow
   screen anyway, which is why it is a layout change rather than a scrollbar. */
@media (max-width: 560px) {
    .tx-spec,
    .tx-spec tbody,
    .tx-spec tr,
    .tx-spec th,
    .tx-spec td {
        display: block;
        width: auto;
    }

    .tx-spec tr { padding: 8px 0; border-bottom: 1px solid var(--tx-line-soft); }
    .tx-spec tr:last-child { border-bottom: 0; }

    .tx-spec th {
        padding: 0 0 2px;
        font-size: 11.5px;
        text-transform: uppercase;
        letter-spacing: .05em;
    }

    .tx-spec td { padding: 0; }
}
