/* ==========================================================================
   Redix Digital: the portfolio page (portfolio.html, tools/build-portfolio.js).
   v2.css draws what it shares with the home page (the bar, the titles, the
   buttons, the world behind); this lays out the work: a title and a filter,
   then each project as a row, its words on one side and the site itself on
   the other, in a laptop with a phone standing at its corner. The rows take
   turns, so the eye goes from side to side down the page. Both screens run
   down their site, slowly, while the row is on the screen.
   ========================================================================== */

/* As on the home page: the shade of a section lies over the sky and under the bird, and what is
   read or shown lies over the bird (the canvases: sky 0, tree and house 1, bird 2) */
.sub-page .pf { position: relative; z-index: auto; }   /* page.css lifts every page's main over the bird */

.pf-top,
.case,
.pf-end {
  position: relative;
  z-index: 3;
}

/* --- The opening ----------------------------------------------------------------- */

.pf-top {
  display: grid;
  align-content: end;
  gap: clamp(24px, 4vh, 40px);
  min-height: min(88svh, 900px);
  padding: calc(var(--nav-h, 80px) + 12vh) var(--pad) clamp(40px, 8vh, 80px);
}

.pf-head { display: grid; justify-items: start; }

/* On a wide screen that is short (1280 by 720) the line under the title stands on the bright line
   of the horizon: a soft pool of deeper night behind the words, fading out on every side
   (measured 3.8:1, 2026-10-19) */
@media (min-width: 900px) and (max-height: 800px) {
  .pf-head { position: relative; }

  .pf-head::before {
    content: "";
    position: absolute;
    z-index: -1;
    inset: -70px calc(-1 * var(--pad));   /* (no wider than the margin: it must not widen the page) */
    background: radial-gradient(closest-side, rgba(7, 11, 26, 0.72) 66%, rgba(7, 11, 26, 0) 100%);
    pointer-events: none;
  }
}

.pf-title { font-size: clamp(3rem, 8vw, 8rem); }

.pf-sub { margin-top: clamp(10px, 1.6vh, 18px); }

/* The filter (redrawn 2026-10-15, Roei: the buttons wrapped onto three rows on a phone, and the
   floating row was cut at the edge). One rail of night glass, its choices side by side, and a
   light that slides to the chosen one (portfolio.js places it), so the eye follows the change.
   The full names where there is room, short ones on a phone, so the rail stays one row; with the
   text made larger it may take a second row, never cut a name. No counts. */
.pf-rail {
  position: relative;
  display: inline-flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 5px;
  border-radius: 16px;
  background: rgba(12, 18, 40, 0.72);
  box-shadow: inset 0 0 0 1px var(--line);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  backdrop-filter: blur(14px) saturate(140%);
}

.pf-filter { justify-self: start; }

.pf-chip {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0 18px;
  border: 0;
  border-radius: 12px;
  background: none;
  color: var(--text-mid);
  font: inherit;
  font-size: 1rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: color 250ms ease;
  -webkit-tap-highlight-color: transparent;
}

.pf-chip[aria-pressed="true"] { color: var(--text); }

.pf-short { display: none; }

/* The light on the chosen one: placed and sized by portfolio.js; it glides only once it has been
   placed, so the page does not open with it flying in */
.pf-light {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  border-radius: 12px;
  background: linear-gradient(180deg, rgba(103, 232, 249, 0.2), rgba(34, 211, 238, 0.08));
  box-shadow: inset 0 0 0 1px rgba(103, 232, 249, 0.55), 0 0 22px -6px rgba(34, 211, 238, 0.6);
  opacity: 0;
  pointer-events: none;
}

.pf-rail.is-lit .pf-light { opacity: 1; }

.pf-rail.is-set .pf-light {
  transition: transform 420ms var(--ease-out-strong), width 420ms var(--ease-out-strong), height 420ms var(--ease-out-strong);
}

/* before the light is placed (or without the script), the chosen one carries it itself */
.pf-rail:not(.is-lit) .pf-chip[aria-pressed="true"] {
  background: rgba(103, 232, 249, 0.14);
  box-shadow: inset 0 0 0 1px rgba(103, 232, 249, 0.55);
}

/* inside the rail the ring of the keyboard is drawn inwards: the rail's edge would cut it */
.pf-chip:focus-visible {
  outline: 2px solid var(--cyan-hi);
  outline-offset: -3px;
}

@media (hover: hover) and (pointer: fine) {
  .pf-chip:not([aria-pressed="true"]):hover { color: var(--text); }
}

.pf-chip:active { transform: scale(0.97); }

@media (max-width: 600px) {
  .pf-filter .pf-long { display: none; }
  .pf-filter .pf-short { display: inline; }
  .pf-chip { padding: 0 15px; }
}

/* The same filter, floating at the foot of the screen while the work goes by (Roei, 2026-10-15),
   in the middle, between the WhatsApp button and the accessibility one. portfolio.js brings it
   up (.is-on) and takes it away. On a wide screen it is the rail itself; on a phone it is one
   button that names what is shown, and the choices open above it (.is-open). */
.pf-float {
  position: fixed;
  z-index: 390;   /* under the corner buttons and their panels (400) */
  bottom: max(24px, env(safe-area-inset-bottom));
  left: 50%;
  max-width: calc(100vw - 2 * (24px + var(--fab-size, 60px) + 16px));
  opacity: 0;
  visibility: hidden;
  transform: translate3d(-50%, 24px, 0);
  transition: opacity 300ms ease, transform 450ms var(--ease-out-strong), visibility 0s linear 450ms;
}

.pf-float.is-on {
  opacity: 1;
  visibility: visible;
  transform: translate3d(-50%, 0, 0);
  transition: opacity 300ms ease, transform 450ms var(--ease-out-strong), visibility 0s;
}

.pf-float-row {
  flex-wrap: nowrap;
  padding: 6px;
  border-radius: 18px;
  background: rgba(12, 18, 40, 0.86);
  box-shadow: inset 0 0 0 1px rgba(194, 205, 232, 0.16), 0 24px 50px -20px rgba(0, 0, 0, 0.8), 0 2px 10px rgba(0, 0, 0, 0.25);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  backdrop-filter: blur(18px) saturate(140%);
}

.pf-float-row .pf-chip { font-size: 0.9375rem; }

.pf-float-toggle { display: none; }

@media (max-width: 999px) {
  .pf-float-row .pf-long { display: none; }
  .pf-float-row .pf-short { display: inline; }
}

html:not(.js) .pf-float { display: none; }

/* what the keyboard reaches stays clear of the floating filter too (v2.css keeps it clear of the
   bar and the round buttons) */
html:has(.pf-float.is-on) { scroll-padding-block-end: 112px; }

@media (max-width: 700px) {
  .pf-float {
    bottom: calc(max(24px, env(safe-area-inset-bottom)) + 4px);
    max-width: none;
  }

  /* the button: what is shown now, and a chevron that points to where the choices open */
  .pf-float-toggle {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    min-height: 48px;
    padding: 0 20px;
    border: 0;
    border-radius: 99px;
    background: rgba(12, 18, 40, 0.9);
    box-shadow: inset 0 0 0 1px rgba(103, 232, 249, 0.42), 0 14px 30px -12px rgba(0, 0, 0, 0.75), 0 0 24px -8px rgba(34, 211, 238, 0.55);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    backdrop-filter: blur(18px) saturate(140%);
    color: var(--text);
    font: inherit;
    font-size: 0.9375rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }

  .pf-float-now { color: var(--cyan-hi); }

  .pf-float-toggle::after {
    content: "";
    width: 7px;
    height: 7px;
    margin-top: 5px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(-135deg);
    transition: transform 260ms var(--ease-out-strong), margin 260ms var(--ease-out-strong);
  }

  .pf-float.is-open .pf-float-toggle::after { margin-top: -4px; transform: rotate(45deg); }

  .pf-float-toggle:focus-visible {
    outline: 2px solid var(--cyan-hi);
    outline-offset: 3px;
  }

  .pf-float-toggle:active { transform: scale(0.97); }

  /* the choices: a pane of the same glass over the button, one under the other, full names */
  .pf-float-row {
    position: absolute;
    bottom: calc(100% + 10px);
    left: 50%;
    flex-direction: column;
    width: max-content;
    min-width: 236px;
    max-width: calc(100vw - 32px);
    opacity: 0;
    visibility: hidden;
    transform: translate3d(-50%, 8px, 0) scale(0.98);
    transform-origin: 50% 100%;
    transition: opacity 200ms ease, transform 260ms var(--ease-out-strong), visibility 0s linear 260ms;
  }

  .pf-float.is-open .pf-float-row {
    opacity: 1;
    visibility: visible;
    transform: translate3d(-50%, 0, 0);
    transition: opacity 200ms ease, transform 260ms var(--ease-out-strong), visibility 0s;
  }

  .pf-float-row .pf-chip {
    justify-content: flex-start;
    min-height: 48px;
    font-size: 1rem;
  }

  .pf-float-row .pf-long { display: inline; }
  .pf-float-row .pf-short { display: none; }

  html:has(.pf-float.is-on) { scroll-padding-block-end: 100px; }
}

/* --- The work ----------------------------------------------------------------------- */

/* The night lies a little deeper behind the whole of the work, as behind every section of text on
   the home page (--veil): one even shade across the screen, fading in and out at the ends of the
   section, so nothing in it moves against the sky as the page scrolls. (Until 2026-10-15 it was a
   dark oval behind each block of words; scrolling, the ovals slid over the line of the horizon
   like stains, Roei.) The sky itself goes quieter still behind the words (uCalm in v2.js). */
.pf-cases {
  position: relative;
  overflow-x: clip;
  background: var(--veil);
  display: grid;
  gap: clamp(88px, 15vh, 170px);
  padding: clamp(24px, 6vh, 64px) var(--pad) clamp(80px, 14vh, 150px);
}

/* A row: the words on the side the page reads from, the site on the other; every other row
   the other way round */
.case {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  align-items: center;
  gap: clamp(32px, 5.5vw, 110px);
  scroll-margin-top: calc(var(--nav-h, 80px) + 24px);
}

.case[hidden] { display: none; }

.case--flip { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.case--flip .case-text { order: 2; }

.case-text {
  position: relative;
  display: grid;
  justify-items: start;
  align-content: center;
}

.case-name {
  margin: 0;
  font-size: clamp(2rem, 3.6vw, 3.5rem);
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.case-type {
  margin: 10px 0 0;
  font-size: clamp(1.125rem, 1.5vw, 1.5rem);
  font-weight: 300;
  line-height: 1.35;
  color: var(--title-thin);
  text-wrap: balance;
}

.case-what {
  max-width: 34em;
  margin: clamp(14px, 2vh, 20px) 0 0;
  color: var(--text-mid);
  text-wrap: pretty;
}

/* The whole story, a press away. It is in the page from the start (a search engine reads it
   too); open, it stands on a pane of the night, so the long text reads in peace */
.case-more { margin-top: clamp(8px, 1.4vh, 14px); }

.case-more summary {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  font-weight: 700;
  color: var(--cyan-hi);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 7px;
  list-style: none;
  cursor: pointer;
  transition: color 160ms ease;
}

.case-more summary::-webkit-details-marker { display: none; }

.case-more summary::after {
  content: "";
  width: 8px;
  height: 8px;
  margin-top: -4px;
  border-inline-end: 2px solid currentColor;
  border-block-end: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform 260ms var(--ease-out-strong);
}

.case-more[open] summary::after { transform: translateY(4px) rotate(-135deg); }

.case-more summary:focus-visible {
  outline: 2px solid var(--cyan-hi);
  outline-offset: 4px;
  border-radius: 4px;
}

@media (hover: hover) and (pointer: fine) {
  .case-more summary:hover { color: #fff; }
}

.case-story {
  max-width: 62ch;
  margin-top: 10px;
  padding: clamp(18px, 2vw, 26px) clamp(18px, 2.2vw, 30px);
  border-radius: 20px;
  background: rgba(7, 11, 26, 0.72);
  box-shadow: inset 0 0 0 1px rgba(125, 240, 244, 0.12);
  color: var(--text-mid);
  line-height: 1.75;
}

.case-story p { margin: 0; text-wrap: pretty; }
.case-story p + p { margin-top: 0.9em; }

/* --- The mockup ----------------------------------------------------------------------
   Drawn in v2.css (the home page's first service pane has it too). Here: which way it faces in
   a row, the old pictures kept near their own width, and how the screens are read. */
.case--flip .mock-laptop { margin-inline: auto 0; }
.case--one .mock-laptop { width: min(100%, var(--natural, 100%)); margin-inline: auto; }
.case--one .mock { padding-bottom: 54px; }
.case--flip .mock-phone { inset-inline: 0 auto; }

/* Nothing on this page runs by itself (Roei, 2026-10-15: "שום דבר לא נגלל אוטומטית"). A screen
   shows the top of its site until it is asked: the pointer over the work, a touch on it, or the
   button under the laptop (portfolio.js sets .is-reading). Then it runs down the site, and back
   up at the same pace when it is let go: a transition turned round midway takes only the part of
   its time it has run. The time of each picture is set by portfolio.js from the length of its
   way, so every site goes by at the same speed. */
html:not(.no-motion) .case .mock-view img {
  animation: none;
  transform: translate3d(0, 0, 0);
  transition: transform 8s linear;
}

html:not(.no-motion) .case .mock.is-reading .mock-view img { transform: translate3d(0, calc(-100% + 100cqh), 0); }

/* Away from the screen a screenshot is only a picture, with no layer of its own: forty tall layers
   at once are more than a phone keeps, and Safari on an iPhone left one of them empty far down
   the page (BECO's phone, 2026-10-15) */
html:not(.no-motion) .case:not(.is-near) .mock-view img { will-change: auto; }

/* Motion stopped: nothing moves by itself or by the pointer; the visitor scrolls the screen */
.no-motion .case .mock-view { overflow-y: auto; }
.no-motion .case .mock-view::after { display: none; }

/* The sign under the laptop: a round of night glass with a mouse whose wheel turns (a finger on a
   touch screen). It turns a few times when the work arrives, then rests; while the screens run it
   steps back. */
.mock-try {
  position: absolute;
  z-index: 2;
  top: calc(100% + 8px);
  left: 50%;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid rgba(125, 240, 244, 0.3);
  border-radius: 50%;
  background: rgba(10, 16, 34, 0.72);
  color: var(--cyan-hi, #7df0f4);
  cursor: pointer;
  transform: translateX(-50%);
  transition: opacity 300ms ease, border-color 300ms ease, box-shadow 300ms ease;
}

.mock-try svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* the wheel of the mouse, in the drawing's place for it */
.mock-try-wheel {
  position: absolute;
  top: calc(50% - 4.6px);
  left: calc(50% - 0.8px);
  width: 1.6px;
  height: 3.2px;
  border-radius: 1px;
  background: currentColor;
}

.mock-try-tap { display: none; }

@media (hover: none), (pointer: coarse) {
  .mock-try { width: 44px; height: 44px; }
  .mock-try-mouse,
  .mock-try-wheel { display: none; }
  .mock-try-tap { display: block; }
}

.mock-try:hover,
.mock.is-reading .mock-try { border-color: rgba(125, 240, 244, 0.6); box-shadow: 0 0 18px -4px rgba(125, 240, 244, 0.55); }

.mock.is-reading .mock-try { opacity: 0.55; }

.mock-try:focus-visible { outline: 2px solid var(--cyan-hi, #7df0f4); outline-offset: 3px; }

@keyframes try-wheel {
  0%, 20% { transform: translate3d(0, 0, 0); opacity: 1; }
  60% { transform: translate3d(0, 4px, 0); opacity: 0; }
  61% { transform: translate3d(0, -1px, 0); opacity: 0; }
  100% { transform: translate3d(0, 0, 0); opacity: 1; }
}

@keyframes try-tap {
  0%, 30%, 100% { transform: none; }
  50% { transform: translate3d(0, 1.5px, 0) scale(0.92); }
}

html:not(.no-motion) .case.is-lit .mock-try-wheel { animation: try-wheel 1.7s ease-in-out 1.4s 3; }
html:not(.no-motion) .case.is-lit .mock-try-tap { transform-origin: 50% 80%; animation: try-tap 1.7s ease-in-out 1.4s 3; }
html:not(.no-motion) .case .mock.is-reading :is(.mock-try-wheel, .mock-try-tap) { animation: none; }

/* No script, or the motion stopped: nothing to ask, the sign goes */
html:not(.js) .mock-try,
.no-motion .mock-try { display: none; }


/* --- The last words ------------------------------------------------------------------- */

.pf-end {
  display: grid;
  justify-items: start;
  gap: clamp(22px, 3.4vh, 34px);
  padding: clamp(60px, 12vh, 140px) var(--pad) clamp(90px, 18vh, 200px);
}

.pf-end-title { font-size: clamp(2.25rem, 5vw, 5rem); }

/* --- Narrower screens: the site above its words ------------------------------------------ */

@media (max-width: 899px) {
  /* the title low in the first screen, so the bird has the sky above it, as on the home page */
  .pf-top { min-height: 74svh; padding-top: calc(var(--nav-h, 72px) + 12vh); }

  .case,
  .case--flip {
    grid-template-columns: minmax(0, 1fr);
    gap: 26px;
  }

  .case-show { order: -1; }
  .case--flip .case-text { order: 0; }

  .mock-laptop,
  .case--flip .mock-laptop { width: 88%; margin-inline: 0 auto; }
  .case--one .mock-laptop { width: min(100%, var(--natural, 100%)); margin-inline: auto; }

  .mock-phone,
  .case--flip .mock-phone { inset-inline: auto 0; width: 25%; }
}

/* --- The accessibility menu's colour modes and the system's forced colours ---------------
   The frames give way to plain outlines; the screens hold still */
html:is(.a11y-contrast, .a11y-negative, .a11y-light) :is(.mock-screen, .mock-phone, .case-story) { box-shadow: none; outline: 2px solid currentColor; outline-offset: -2px; }
html:is(.a11y-contrast, .a11y-negative, .a11y-light) .pf-chip { outline: 2px solid currentColor; outline-offset: -2px; }
html:is(.a11y-contrast, .a11y-negative, .a11y-light) .pf-chip[aria-pressed="true"] { outline-width: 4px; text-decoration: underline; text-underline-offset: 6px; }
html:is(.a11y-contrast, .a11y-negative, .a11y-light) .pf-light { display: none; }
html:is(.a11y-contrast, .a11y-negative, .a11y-light) .mock-view img { animation: none !important; }
html:is(.a11y-contrast, .a11y-negative, .a11y-light) :is(.pf-rail, .pf-float-toggle) { outline: 1px solid currentColor; }

/* With the motion stopped the floating filter and its choices simply appear and go, and the
   light stands on the chosen one without gliding */
.no-motion :is(.pf-float, .pf-float-row, .pf-light),
.no-motion .pf-float-toggle::after { transition-duration: 1ms !important; transition-delay: 0s !important; }

@media (forced-colors: active) {
  .pf-chip { border: 1px solid ButtonText; }
  .pf-chip[aria-pressed="true"] { outline: 3px solid Highlight; }
  .pf-light { display: none; }
  :is(.pf-rail, .pf-float-toggle) { background-color: Canvas; border: 1px solid CanvasText; }
  .mock-screen,
  .mock-phone,
  .case-story { border: 1px solid CanvasText; }
  .mock-view img { animation: none !important; }
}

/* English pages: the short English names are longer than the Hebrew ones, so on a phone the
   choices sit a little closer, to keep the rail on one line down to 360px */
@media (max-width: 600px) {
  html[dir="ltr"] .pf-chip { padding: 0 11px; font-size: 0.9375rem; }
}
@media (max-width: 380px) {
  html[dir="ltr"] .pf-chip { padding: 0 8px; }
}

