/*  v2.css  —  styles for the feature overlay.
 *
 *  Loaded by ALL FOUR pages — index.html, mobile.html, v2.html, v2-mobile.html
 *  — always AFTER app.css / mobile.css. Because it comes last in the cascade,
 *  a rule of equal specificity here wins.
 *
 *  ⚠️ That is a sharp edge, not a convenience. A rule here that ties an
 *  app.css rule on specificity overrides it silently, and two such collisions
 *  have already shipped bugs (see PROMOTE-V2.md 1.3 and 4.7) — both fixed by
 *  adding :not(...) to raise this side's specificity deliberately. When you
 *  override a shared rule, make the win explicit rather than leaning on order.
 *
 *  Scope every rule by page, so the desktop and mobile pages stay independent:
 *      .v2          all four pages
 *      .v2_desktop  index.html + v2.html
 *      .v2_mobile   mobile.html + v2-mobile.html
 *  The classes are set statically on <body>, so there is no flash of
 *  unstyled content while the scripts boot.
 *
 *  Test-page chrome (#v2_badge, #v2_gate) lives in v2-test.css.
 */


/* ====================================================================
 *  EXPERIMENTS
 *
 *  One block per experiment, keyed by the same id used in app/v2.js.
 *  Keep them in the same order as the JS registry.
 * ==================================================================== */

/*  --- login-autofocus ---------------------------------------------- */
/*  No styles needed. */


/*  --- category-home -------------------------------------------------
 *
 *  Visibility is driven by two body classes set from v2.js:
 *      .v2_home_on   the experiment is active
 *      .v2_at_home   currently on the category screen, no category open
 *
 *  app.filter() calls hide()/fadeIn() on #activity_boxes_wrapper, which
 *  writes inline styles — so the rules that have to beat it are !important.
 *  Ours (#v2_home, #v2_back) are untouched by the app and need no help.
 * ------------------------------------------------------------------- */

/* the category filter is what this screen replaces */
.v2_home_on #filter_box_cat { display: none; }

.v2_home_on #v2_home,
.v2_home_on #v2_back { display: none; }

.v2_home_on.v2_at_home #v2_home { display: block; }
.v2_home_on:not(.v2_at_home) #v2_back { display: flex; }

/* on the category screen the list and the remaining filters are irrelevant */
.v2_home_on.v2_at_home #activity_boxes_wrapper,
.v2_home_on.v2_at_home #filter_box_wrapper,
.v2_home_on.v2_at_home #ico_filter { display: none !important; }

.v2_home_title {
    margin: 26px 0 20px;
    font-size: 21px;
    font-weight: 700;
    text-align: center;
    color: #3a4048;
}

.v2_home_grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 14px;
    max-width: 860px;
    margin: 0 auto 32px;
    padding: 0 14px;
}

.v2_cat_card {
    position: relative;
    padding: 20px 22px;
    border-radius: 12px;
    background: #fff;
    box-shadow: 0 1px 4px rgba(0, 0, 0, .10);
    cursor: pointer;
    overflow: hidden;
    transition: transform .13s ease, box-shadow .13s ease;
}

.v2_cat_card::before {          /* RTL: accent runs down the right edge */
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    width: 5px;
    height: 100%;
    background: var(--v2-accent, #3085d6);
}

.v2_cat_card:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 18px rgba(0, 0, 0, .14);
}

.v2_cat_card:active { transform: translateY(0); }

.v2_cat_name {
    margin-bottom: 6px;
    font-size: 18px;
    font-weight: 700;
    color: #2b3038;
}

.v2_cat_count {
    font-size: 13px;
    color: #7d8792;
}

/*  --- last-year-category --------------------------------------------
 *  Virtual category, first in the grid. Deliberately distinct from the
 *  five real ones so it does not read as another sheet category.
 * ------------------------------------------------------------------- */
.v2_cat_last {
    --v2-accent: #d4a017;
    background: linear-gradient(180deg, #fffaef 0%, #fff 60%);
}

.v2_cat_last .v2_cat_name::before {
    content: "★";
    margin-left: 7px;
    color: #d4a017;
    font-size: 15px;
}

/*  The card holds its place in the grid from the first paint and only swaps
 *  its own text, so the layout never shifts when the background lookup for
 *  last year's signups comes back.
 */
.v2_cat_disabled {
    cursor: default;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .06);
    background: #fbfbfc;
}

.v2_cat_disabled .v2_cat_name { color: #9aa3ad; }
.v2_cat_disabled .v2_cat_name::before { color: #c3c9d0; }
.v2_cat_disabled .v2_cat_count { color: #a8b0b9; }
.v2_cat_disabled::before { background: #dfe3e8; }

.v2_cat_disabled:hover {
    transform: none;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .06);
}

.v2_cat_loading .v2_cat_count {
    animation: v2_pulse 1.25s ease-in-out infinite;
}

@keyframes v2_pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: .42; }
}

@media (prefers-reduced-motion: reduce) {
    .v2_cat_loading .v2_cat_count { animation: none; }
}

/*  Last in the grid, and like the last-year card deliberately not one of the
 *  five sheet categories — neutral grey rather than another colour, so it
 *  reads as "no filter" instead of as one more category. */
.v2_cat_all {
    --v2-accent: #8b95a1;
    background: linear-gradient(180deg, #f7f8fa 0%, #fff 60%);
}

.v2_cat_all .v2_cat_name::before {
    content: "≡";
    margin-left: 7px;
    color: #8b95a1;
    font-size: 15px;
}

.v2_cat_c0 { --v2-accent: #3085d6; }
.v2_cat_c1 { --v2-accent: #e8a33d; }
.v2_cat_c2 { --v2-accent: #4caf82; }
.v2_cat_c3 { --v2-accent: #b06ab3; }
.v2_cat_c4 { --v2-accent: #e2705f; }

#v2_back {
    align-items: center;
    gap: 14px;
    margin: 14px auto 6px;
    max-width: 860px;
    padding: 0 14px;
}

#v2_back_bt {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 14px 6px 12px;
    border-radius: 999px;
    background: #eceff3;
    color: #4a525c;
    font-size: 14px;
    cursor: pointer;
    white-space: nowrap;
}

#v2_back_bt:hover { background: #e0e4ea; color: #2b3038; }

.v2_back_arrow { font-size: 16px; line-height: 1; }

#v2_back_current {
    font-size: 17px;
    font-weight: 700;
    color: #2b3038;
}

/*  --- desktop-desc-popup ---------------------------------------------
 *  The collapsed card no longer shows a 4.1em scrolling sliver of text;
 *  the full description lives in the existing maximized view, reached by
 *  an always-visible button instead of a hover-only icon.
 * ------------------------------------------------------------------- */

.v2_desktop.v2_descd_on .activity_box_desc { display: none; }

/* in the maximized modal the description is the point — show it, and drop
   the button, which would only lead back to where the reader already is */
.v2_desktop.v2_descd_on .activity_box.box_maximized .activity_box_desc { display: block; }
.v2_desktop.v2_descd_on .activity_box.box_maximized .v2_descd_bt { display: none; }

.v2_descd_bt {
    display: block;
    margin: 0.5em;
    padding: 6px 12px;
    border: 1px solid #d6dbe2;
    border-radius: 6px;
    background: #f6f8fa;
    color: #3f4852;
    font-size: 0.95em;
    text-align: center;
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
    transition: background .13s ease, border-color .13s ease;
}

.v2_descd_bt::before {
    content: "";
    display: inline-block;
    width: 1em;
    height: 1em;
    margin-left: 7px;
    vertical-align: -2px;
    background: url(../img/maximize.svg) no-repeat center / contain;
    opacity: .65;
}

.v2_descd_bt:hover {
    background: #eef1f5;
    border-color: #c3cad3;
    color: #1f262e;
}


/*  --- login-whatsapp ---------------------------------------------------
 *  Replaces the grey, unclickable "register" text on the login screen. The
 *  mark is an inline data URI rather than a file in img/, so the experiment
 *  stays inside the two v2.* files and adds no request.
 * ------------------------------------------------------------------- */

#v2_login_wa {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 11px 22px;
    border-radius: 999px;
    background: #25d366;
    color: #fff;
    font-size: 17px;
    font-weight: 700;
    text-decoration: none;
    text-shadow: none;              /* mobile.css puts a white glow on the old link */
}

#v2_login_wa::before {
    content: "";
    width: 22px;
    height: 22px;
    flex: 0 0 auto;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ffffff'%3E%3Cpath d='M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.872.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413Z'/%3E%3C/svg%3E") no-repeat center / contain;
}

#v2_login_wa:hover  { background: #1eb955; }
#v2_login_wa:active { background: #1aa64c; }

/* the mobile login screen runs a larger type scale throughout */
.v2_mobile #v2_login_wa { font-size: 19px; padding: 13px 26px; gap: 11px; }
.v2_mobile #v2_login_wa::before { width: 25px; height: 25px; }


/*  --- grade-dialog-layout ---------------------------------------------
 *  app.css sets justify-content:right together with text-align:left on the
 *  same label, and a 24px font that overflows — hence the ragged checkboxes.
 *  A two-column grid puts every box on one axis and every label on another.
 * ------------------------------------------------------------------- */

.v2_gradedlg_on .dlg_form {
    display: flex;
    flex-direction: column;
    gap: 2px;
    width: 100%;
    direction: rtl;
}

.v2_gradedlg_on .dlg_form label {
    display: grid;
    grid-template-columns: 1.15em 1fr;   /* checkbox column, then text */
    align-items: center;
    gap: 12px;
    width: 100%;
    margin: 0;
    padding: 9px 10px;
    border-radius: 7px;
    font-size: 17px;
    line-height: 1.4;
    text-align: right;
    white-space: normal;                 /* long grade names may wrap */
    cursor: pointer;
}

.v2_gradedlg_on .dlg_form label:hover { background: #f2f5f8; }

/*  --- grade-quota ------------------------------------------------------
 *  Remaining places per grade, and a locked look for a full one.
 * ------------------------------------------------------------------- */

.v2_grade_left {
    justify-self: end;
    padding: 2px 9px;
    border-radius: 999px;
    background: #eef1f5;
    color: #6b7480;
    font-size: 13px;
    white-space: nowrap;
}

.v2_grade_left_full { background: #fdeaea; color: #b3453a; font-weight: 600; }

.v2_gradedlg_on .dlg_form label.v2_grade_full {
    color: #a7aeb6;
    cursor: not-allowed;
}

.v2_gradedlg_on .dlg_form label.v2_grade_full:hover { background: none; }

/* the note sits in a third column so the labels stay aligned */
.v2_gradedlg_on .dlg_form label { grid-template-columns: 1.15em 1fr auto; }

.v2_gradedlg_on .dlg_form input[type="checkbox"]:disabled { cursor: not-allowed; }

.v2_gradedlg_on .dlg_form input[type="checkbox"] {
    width: 1.15em;
    height: 1.15em;
    margin: 0;
    cursor: pointer;
}


/*  --- mobile-desc-collapse -------------------------------------------
 *  Descriptions are long; with every one expanded the list becomes
 *  unscannable. Hidden by default, opened per card by its own button.
 * ------------------------------------------------------------------- */

.v2_mobile.v2_desc_on .activity_box_desc { display: none; }
.v2_mobile.v2_desc_on .activity_box.v2_desc_open .activity_box_desc { display: block; }

/* block + auto margins rather than inline-block, so the pill is centred on the
   card instead of hugging its right edge. fit-content keeps it hugging its own
   text; -webkit- for the older iOS versions still in use here. */
.v2_desc_bt {
    display: block;
    width: -webkit-fit-content;
    width: fit-content;
    margin: 4px auto 10px;
    padding: 10px 26px;
    border-radius: 999px;
    background: #eef1f5;
    color: #3f4852;
    /* px, not em — .activity_box is 1.5em on mobile, so an em here would
       inherit a size meant for the card's own text */
    font-size: 17px;
    font-weight: 600;
    line-height: 1.4;
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
}

.v2_desc_bt::after {
    content: "▾";
    display: inline-block;
    margin-right: 7px;
    font-size: 12px;
    transition: transform .15s ease;
}

.v2_desc_bt_open { background: #e2e6ec; color: #2b3038; }
.v2_desc_bt_open::after { transform: rotate(180deg); }

.v2_mobile .v2_home_title { margin: 18px 0 16px; font-size: 19px; }
.v2_mobile .v2_home_grid  { grid-template-columns: 1fr; gap: 11px; padding: 0 12px; }
.v2_mobile .v2_cat_card   { padding: 16px 18px; }
.v2_mobile #v2_back       { margin: 10px auto 4px; }


/*  --- filter-pills -----------------------------------------------------
 *
 *  Two problems in app.css, both fixed here without touching the HTML:
 *
 *  1. Horizontal scrolling. .filter_box is white-space:nowrap (app.css:508)
 *     inside a wrapper with overflow:auto (app.css:503), so the six long
 *     labels of the "תזמון" row always spill into a scrollbar. The 15em
 *     start-side padding on .filter_box (app.css:507) makes it worse.
 *     Here the row wraps instead.
 *
 *  2. Rows not lining up. .filter_box_title is an inline-block of natural
 *     width (app.css:512), so a wide title and a narrow one start their
 *     rows at different offsets. Here the title gets a fixed column and is
 *     pulled back into the row's own padding — a hanging indent, so the
 *     first line and every wrapped line begin at the same place.
 *
 *  The checkbox is swapped for a pill. It stays in the DOM, visually
 *  hidden rather than display:none, so it is still tabbable and the change
 *  event still fires. The checked state is drawn with input:checked + span,
 *  a plain sibling selector — no dependency on :has(). app.js:844 already
 *  forwards a click anywhere on the item to the input, so the whole pill is
 *  the hit target for free.
 *
 *  Desktop only: mobile.css:709 gives the filters a vertical panel of their
 *  own, which has neither problem.
 * ------------------------------------------------------------------- */

.v2_filter_pills {
    --v2-filter-label: 8em;         /* fits the widest title, "מעגל השפעה:" */
    /* #header_logo is absolute at right:4em and 10em wide (app.css:357), inside
       a sticky header it overhangs — it lands on top of the first filter row.
       Its start edge is 14em in, so the row has to begin past that. This is
       what the 15em in app.css:507 was for; it has to be restated here because
       the padding shorthand on .filter_box below replaces that rule outright.
       Uniform across rows, so the title column stays aligned even though only
       the first row is actually covered. */
    --v2-filter-gutter: 15em;
    /* app.css:518 already uses this blue on the filter hover border. Swapping
       it for var(--campaign-color) would tie the row to the campaign theme,
       but that colour comes from the sheet and may be too light to carry
       white text — hence a fixed, known-contrast accent. */
    --v2-filter-accent: #1b74e4;
}

.v2_filter_pills #filter_box_wrapper {
    padding: 10px 0;
    overflow: visible;              /* was auto — this was the scrollbar */
}

.v2_filter_pills .filter_box {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    white-space: normal;            /* was nowrap */
    padding: .55em 1em;
    padding-inline-start: calc(var(--v2-filter-gutter) + var(--v2-filter-label));
    border-bottom: 1px dotted #dfe4ea;
}

.v2_filter_pills .filter_box:last-child { border-bottom: 0; }

.v2_filter_pills .filter_box_title {
    flex: 0 0 var(--v2-filter-label);
    margin-inline-start: calc(-1 * var(--v2-filter-label));
    padding-left: 0;                /* app.css:544 */
    text-decoration: none;          /* the underline reads as noise beside pills */
    font-weight: 700;
    color: #3a4048;
}

/* the item div is now only a hit target — the pill itself is its <span> */
.v2_filter_pills .filter_box_item,
.v2_filter_pills .filter_box_item:hover {
    position: relative;
    margin: .22em .3em;
    padding: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;               /* app.css:517 glows the wrapper */
}

.v2_filter_pills .filter_box input[type="checkbox"] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    opacity: 0;
    transform: none;                /* app.css:535 scales it 1.5x */
    pointer-events: none;
}

.v2_filter_pills .filter_box_item > span {
    display: inline-block;
    padding: .38em .95em;
    border: 1px solid #ccd4de;
    border-radius: 999px;
    background: #fff;
    color: #3a4048;
    line-height: 1.5;
    white-space: nowrap;            /* wrap between pills, never inside one */
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
    -webkit-user-select: none;
    user-select: none;
}

.v2_filter_pills .filter_box_item:hover > span {
    border-color: var(--v2-filter-accent);
    color: var(--v2-filter-accent);
}

/* one class deeper than the hover rule above, so a checked pill keeps its
   fill instead of flipping back to the outline on hover */
.v2_filter_pills .filter_box input:checked + span {
    background: var(--v2-filter-accent);
    border-color: var(--v2-filter-accent);
    color: #fff;
}

.v2_filter_pills .filter_box_item:hover input:checked + span {
    filter: brightness(1.1);
}

.v2_filter_pills .filter_box input:focus-visible + span {
    outline: 2px solid var(--v2-filter-accent);
    outline-offset: 2px;
}


/*  --- activity-circle-badge --------------------------------------------
 *
 *  A full-width strip along the bottom of the card, quiet tint, plain text.
 *  It names the field ("מעגל השפעה") and not just the value, so it reads on
 *  its own without a legend and without a symbol to decode.
 *
 *  Positioned absolutely rather than in flow, so it spans the card's full
 *  width including the 10px padding, instead of being inset by it. On desktop
 *  it then costs no height at all — see the next block for why.
 *
 *  overflow:hidden so the strip is clipped to the card's 10px corner radius
 *  on desktop; mobile has square corners and is unaffected.
 * ------------------------------------------------------------------- */

/*  :not(.box_maximized) on the position is load-bearing. app.css:1128 positions
 *  the maximized card at the same specificity as this rule, and v2.css loads
 *  later — so an unguarded `position: relative` wins, drops the dialog back
 *  into the document flow, and it opens at the clicked card's own position
 *  instead of centred. overflow stays on both: it clips the strip to the card's
 *  corner radius in either state. */
.v2_circle_on .activity_box:not(.box_maximized) {
    position: relative;
}

.v2_circle_on .activity_box {
    overflow: hidden;
}

/*  Room for the strip, without making the card any taller.
 *
 *  min-height:15.5em (app.css:417) applies to the card's CONTENT box, so a
 *  desktop card is pinned at 210.8 + 10 + 10 = 230.8px no matter what its
 *  children do — shrinking them changes nothing, and any padding-bottom adds
 *  height one for one. The strip therefore goes into the content box's own
 *  slack: the children only fill ~209 of the 210.8 they are given, and the two
 *  rules below free the rest. Measured result is 230.8px with the strip, the
 *  same as without, and 6.2px of clearance above it.
 *
 *  The toolbox's 16px top padding is pure air. The description keeps about
 *  three visible lines at 3.6em, and it is a fixed-height scroller either way
 *  (app.css:452), so nothing becomes unreachable. */
/*  :not(.box_maximized) matters. app.css:1147 gives the description height:auto
 *  once the card is blown up into the dialog, at the same specificity as this
 *  rule — and v2.css loads later, so without the guard this would win and clamp
 *  the popup's description to 3.6em too. */
.v2_desktop.v2_circle_on .activity_box:not(.box_maximized) .activity_box_desc {
    height: 3.6em;                  /* app.css:452 has 4.1em */
}

.v2_circle_on .activity_box_toolbox {
    padding-top: 8px;               /* app.css:795 has 16px */
}

/*  Mobile has no min-height, and mobile-desc-collapse already hides the
 *  description, so there is no slack to reclaim — there the strip costs its
 *  own height and nothing else can be given up for it. */
.v2_mobile.v2_circle_on .activity_box {
    padding-bottom: 1.6em;
}

/*  Same story once the card is blown up into the dialog: the description grows
 *  to auto (app.css:1147), so the card is taller than min-height and there is
 *  no slack left at the bottom — the strip was landing on the join button,
 *  covering it by 11px. Room has to be made explicitly here too.
 *  Desktop only: box_maximized never happens on mobile. */
.v2_desktop.v2_circle_on .activity_box.box_maximized {
    padding-bottom: 2.1em;
}

.v2_circle_on .v2_circle {
    position: absolute;
    right: 0;
    left: 0;
    bottom: 0;
    padding: .25em .9em;
    font-size: .75em;
    line-height: 1.5;
    text-align: right;
    -webkit-user-select: none;
    user-select: none;
}

.v2_circle_ttl { opacity: .7; }
.v2_circle_txt { font-weight: 700; }

/*  One hue, tint deepening as the reach widens, so "wider" is legible at a
 *  glance without adding new colours to a page that already carries the
 *  campaign colour, green points and blue buttons. */
.v2_circle_1 { background: #eff4fb; color: #24598f; }
.v2_circle_2 { background: #e4edf8; color: #1d4a7c; }
.v2_circle_3 { background: #d8e5f4; color: #163c66; }

/*  A value the sheet no longer matches: correct text, neutral styling,
 *  rather than something silently broken. */
.v2_circle_0 { background: #eef0f2; color: #5a6470; }
