/* index.css */


/* ==========================================================================
   PAGE
   ========================================================================== */

html,
body {

  width: 100%;
  height: 100%;

  margin: 0;
  padding: 0;

  overflow: hidden;

  background: #ffffff;

  font-family:
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    "Microsoft YaHei",
    "PingFang SC",
    Arial,
    sans-serif;

}


/* ==========================================================================
   EXPERIMENT INSTRUCTION OVERLAY
   ========================================================================== */

.instruction-overlay {

  position: fixed;

  inset: 0;

  z-index: 20000;

  display: flex;

  align-items: center;

  justify-content: center;

  box-sizing: border-box;

  padding:
    max(
      12px,
      env(safe-area-inset-top, 0px)
    )
    max(
      12px,
      env(safe-area-inset-right, 0px)
    )
    max(
      12px,
      env(safe-area-inset-bottom, 0px)
    )
    max(
      12px,
      env(safe-area-inset-left, 0px)
    );

  background: #ffffff;

}


.instruction-panel {

  width:
    min(
      94vw,
      900px
    );

  max-height: 96vh;

  display: flex;

  flex-direction: column;

  align-items: center;

  justify-content: center;

  gap: 18px;

  box-sizing: border-box;

}


.instruction-image {

  display: block;

  width: auto;

  max-width: 100%;

  max-height:
    calc(
      96vh - 90px
    );

  object-fit: contain;

  user-select: none;

  -webkit-user-drag: none;

}


.instruction-confirm-btn {

  flex:
    0 0 auto;

  min-width: 240px;

  min-height: 54px;

  padding:
    0 28px;

  border: none;

  border-radius: 12px;

  background: #007aff;

  color: #ffffff;

  font-family: inherit;

  font-size: 19px;

  font-weight: 800;

  line-height: 1.2;

  text-align: center;

  cursor: pointer;

  touch-action: manipulation;

}


.instruction-confirm-btn:active {

  transform:
    translateY(1px);

}



/* ==========================================================================
   MAIN STAGE
   ========================================================================== */

#stage {

  position: relative;

  width: 100vw;
  height: 100dvh;

  overflow: hidden;

  box-sizing: border-box;

  background: #ffffff;

  padding-left:
    env(
      safe-area-inset-left,
      0
    );

  padding-right:
    env(
      safe-area-inset-right,
      0
    );

  padding-top:
    env(
      safe-area-inset-top,
      0
    );

  padding-bottom:
    env(
      safe-area-inset-bottom,
      0
    );

  --rand-font-size:
    clamp(
      32px,
      10vw,
      140px
    );

}



/* ==========================================================================
   VIDEO + CANVAS
   ========================================================================== */

#vdo,
#cvs {

  position: absolute;

  inset: 0;

  width: 100%;
  height: 100%;

  /*
    Mirror the participant-facing camera display.

    Both the video and the MediaPipe canvas are
    horizontally flipped so that the participant
    experiences the screen like a real mirror.

    IMPORTANT:
    This is display-only.
    Raw MediaPipe landmark coordinates and CSV data
    are not modified by this CSS.
  */

  transform:
    scaleX(-1);

  transform-origin:
    center center;

  -webkit-transform:
    scaleX(-1);

  -webkit-transform-origin:
    center center;

}


/* --------------------------------------------------------------------------
   Camera video
   -------------------------------------------------------------------------- */

#vdo {

  z-index: 1;

  object-fit: contain;

  background: #ffffff;

  opacity: 1;

  pointer-events: none;

}


/* --------------------------------------------------------------------------
   MediaPipe canvas
   -------------------------------------------------------------------------- */

#cvs {

  z-index: 9999;

  background: transparent;

  pointer-events: none;

}



/* ==========================================================================
   HAND STATUS
   ========================================================================== */

.status-text {

  position: absolute;

  top: 12px;
  left: 12px;

  z-index: 10002;

  font-size:
    calc(
      var(--rand-font-size) /
      2
    );

  font-weight: 800;

  line-height: 1;

  color: #bbbbbb;

  user-select: none;

  pointer-events: none;

  text-shadow:
    0 1px 2px
    rgba(
      0,
      0,
      0,
      0.4
    );

}


.status-text.ok {

  color: #00c853;

}


.status-text.ng {

  color: #ff5252;

}



/* ==========================================================================
   RANDOM TEST UI
   ========================================================================== */

.random-ui {

  position: absolute;

  inset: 0;

  z-index: 10000;

  display: grid;

  place-items: center;

  pointer-events: none;

}



/* ==========================================================================
   CONTROL BAR
   ========================================================================== */

.random-form {

  position: absolute;

  top: 6%;
  left: 50%;

  transform:
    translateX(-50%);

  display: flex;

  align-items: center;

  justify-content: center;

  gap: 16px;

  max-width:
    calc(
      100vw - 24px
    );

  box-sizing: border-box;

  padding:
    14px 16px;

  border:
    1px solid #d0d0d0;

  border-radius: 14px;

  background:
    rgba(
      255,
      255,
      255,
      0.94
    );

  box-shadow:
    0 8px 24px
    rgba(
      0,
      0,
      0,
      0.12
    );

  pointer-events: auto;

}



/* ==========================================================================
   PARTICIPANT INFORMATION
   ========================================================================== */

.participant-info {

  font-size: 18px;

  font-weight: 700;

  color: #111111;

  white-space: nowrap;

}


.study-error {

  max-width: 420px;

  font-size: 15px;

  font-weight: 700;

  color: #d32f2f;

}



/* ==========================================================================
   START BUTTON
   ========================================================================== */

.rnd-btn {

  min-width: 100px;

  min-height: 46px;

  padding:
    0 20px;

  border: none;

  border-radius: 10px;

  background: #007aff;

  color: #ffffff;

  font-family: inherit;

  font-size: 18px;

  font-weight: 800;

  cursor: pointer;

  touch-action: manipulation;

}


.rnd-btn[disabled] {

  background: #f6d6d6;

  color: #9b3a3a;

  border:
    1px solid #e7bcbc;

  opacity: 1;

  cursor: not-allowed;

}



/* ==========================================================================
   CENTER TARGET
   ========================================================================== */

.random-box {

  position: relative;

  width:
    min(
      56vw,
      720px
    );

  height:
    min(
      38vh,
      420px
    );

  display: flex;

  align-items: center;

  justify-content: center;

  box-sizing: border-box;

  border:
    3px solid #111111;

  border-radius: 18px;

  background:
    rgba(
      247,
      247,
      247,
      0.90
    );

  box-shadow:
    0 8px 26px
    rgba(
      0,
      0,
      0,
      0.20
    );

  pointer-events: none;

}


.random-number {

  display: inline-block;

  line-height: 1;

  color: #111111;

  font-size: 14vmin;

  font-weight: 900;

  user-select: none;

}


/*
  Participant-facing target: name + number both read at comparable
  size (user feedback 2026-09-06 — some participants read the digit
  labeled on their finger, others read the finger name; neither
  should be hard to see). Name stays marginally larger to keep it
  the primary reading path, but the number is no longer a tiny
  footnote.
*/

.finger-jp-name {

  display: block;

  line-height: 1.05;

  font-size: 0.82em;

  /*
    CJK text has no spaces, so the browser default would wrap it
    mid-word ("右示指" -> "右" / "示" / "指" stacked one per line)
    once the box gets narrow, which blows up the element's height
    far beyond what fitText()'s shrink loop can recover from.
    Force it onto one line so fitText() always measures a single
    line and can size against it correctly.
  */
  white-space: nowrap;

}


.finger-number-secondary {

  display: block;

  line-height: 1;

  font-size: 0.66em;

  font-weight: 800;

  color: #333333;

  margin-top: 0.12em;

  white-space: nowrap;

}



/* ==========================================================================
   INITIAL HAND-POSITION HINT
   ========================================================================== */

.random-box.initial-hint-mode {

  border:
    3px solid #8aa8c7;

  background:
    rgba(
      245,
      249,
      253,
      0.94
    );

}


.random-number.initial-hint {

  display: block;

  width: 88%;
  max-width: 560px;

  box-sizing: border-box;

  margin: 0 auto;

  padding:
    12px 16px;

  color: #355b7d !important;

  font-size:
    clamp(
      22px,
      4vmin,
      38px
    ) !important;

  font-weight: 800;

  line-height: 1.45;

  text-align: center;

  white-space: normal;

  overflow-wrap: anywhere;

  word-break: normal;

  hyphens: none;

  -webkit-text-size-adjust: 100%;

  text-size-adjust: 100%;

}



/* ==========================================================================
   COUNTDOWN MODE
   ========================================================================== */

.random-box.countdown-mode {

  border:
    3px solid #7aa7d9;

  background:
    rgba(
      242,
      247,
      252,
      0.96
    );

}


.random-box.countdown-mode::before {

  content:
    attr(
      data-countdown-label
    );

  position: absolute;

  top: 22px;
  left: 50%;

  transform:
    translateX(-50%);

  color: #4f6f91;

  font-family: inherit;

  font-size:
    clamp(
      20px,
      3.5vmin,
      30px
    );

  font-weight: 800;

  line-height: 1;

  letter-spacing: 0.08em;

  white-space: nowrap;

}


.random-number.countdown {

  min-width: 1.55em;

  min-height: 1.55em;

  display: inline-flex;

  align-items: center;

  justify-content: center;

  box-sizing: border-box;

  padding: 0.16em;

  border:
    4px solid #7aa7d9;

  border-radius: 50%;

  background: #e8f1fb;

  color: #4f6f91 !important;

  font-size:
    clamp(
      64px,
      10vmin,
      120px
    ) !important;

  font-weight: 800;

  line-height: 1;

}



/* ==========================================================================
   FORMAL TRIAL FEEDBACK
   ========================================================================== */

.random-number.match {

  color: #00c853 !important;

}


.random-number.mismatch {

  color: #ff3b30 !important;

}



/* ==========================================================================
   EXPERIMENT PROGRESS BAR
   ========================================================================== */

.progress-bar {

  position: absolute;

  top: 0;
  left: 0;
  right: 0;

  height: 6px;

  z-index: 10001;

  background:
    rgba(
      0,
      0,
      0,
      0.15
    );

  pointer-events: none;

}


.progress-fill {

  width: 0%;

  height: 100%;

  background: #00b894;

  transition:
    width 0.2s ease;

}


.progress-text {

  position: absolute;

  top: 8px;
  left: 50%;

  transform:
    translateX(-50%);

  padding:
    2px 8px;

  border-radius: 999px;

  background:
    rgba(
      255,
      255,
      255,
      0.90
    );

  color: #333333;

  font-size: 13px;

  font-weight: 700;

  white-space: nowrap;

}



/* ==========================================================================
   MODEL LOADING
   ========================================================================== */

.model-loading {

  position: absolute;

  left: 50%;
  bottom: 8%;

  transform:
    translateX(-50%);

  width:
    min(
      80vw,
      440px
    );

  z-index: 10004;

  box-sizing: border-box;

  padding:
    14px 16px;

  border:
    1px solid
    rgba(
      0,
      0,
      0,
      0.15
    );

  border-radius: 14px;

  background:
    rgba(
      255,
      255,
      255,
      0.96
    );

  text-align: center;

  box-shadow:
    0 6px 20px
    rgba(
      0,
      0,
      0,
      0.15
    );

  pointer-events: none;

}


.model-loading-text {

  margin-bottom: 10px;

  color: #222222;

  font-size: 16px;

  font-weight: 700;

}


.model-loading-bar {

  width: 100%;

  height: 12px;

  overflow: hidden;

  border-radius: 999px;

  background: #dedede;

}


.model-loading-fill {

  width: 0%;

  height: 100%;

  border-radius: inherit;

  background: #007aff;

  transition:
    width 0.15s linear;

}


.model-loading-percent {

  margin-top: 8px;

  color: #222222;

  font-size: 19px;

  font-weight: 800;

  font-variant-numeric:
    tabular-nums;

}



/* ==========================================================================
   FINGER LABEL TOGGLE
   ========================================================================== */

.label-toggle-btn {

  position: absolute;

  right: 12px;
  bottom: 12px;

  z-index: 10003;

  min-height: 44px;

  padding:
    0 16px;

  border: none;

  border-radius: 999px;

  background: #ffffff;

  color: #111111;

  font-family: inherit;

  font-size: 14px;

  font-weight: 700;

  box-shadow:
    0 6px 18px
    rgba(
      0,
      0,
      0,
      0.20
    );

  cursor: pointer;

  pointer-events: auto;

}


.label-toggle-btn:disabled {

  opacity: 0.55;

  cursor: not-allowed;

}



/* ==========================================================================
   DEVELOPMENT BADGE
   ========================================================================== */

.badge {

  position: fixed;

  left: 12px;
  bottom: 10px;

  z-index: 2;

  color: #777777;

  font-size: 12px;

  line-height: 1.4;

  pointer-events: none;

}



/* ==========================================================================
   TABLET / MOBILE
   ========================================================================== */

@media
(max-width: 768px) {

  .instruction-panel {

    width: 100%;

    gap: 14px;

  }


  .instruction-confirm-btn {

    min-width: 220px;

    min-height: 52px;

    font-size: 18px;

  }


  .random-form {

    top: 4%;

    gap: 12px;

    flex-wrap: wrap;

  }


  .participant-info {

    font-size: 16px;

  }


  .rnd-btn {

    min-height: 44px;

    font-size: 16px;

  }


  .random-box {

    width:
      min(
        88vw,
        680px
      );

    height:
      min(
        44vh,
        420px
      );

  }


  .random-number {

    font-size: 16vmin;

  }


  .random-number.initial-hint {

    width: 88%;

    max-width: 88%;

    padding:
      10px 12px;

    font-size:
      clamp(
        20px,
        5vw,
        30px
      ) !important;

    line-height: 1.45;

  }


  .random-box.countdown-mode::before {

    top: 18px;

  }


  .random-number.countdown {

    font-size:
      clamp(
        60px,
        15vmin,
        105px
      ) !important;

  }


  .model-loading {

    bottom: 9%;

    width:
      min(
        88vw,
        440px
      );

  }

}



/* ==========================================================================
   SMALL PHONE
   ========================================================================== */

@media
(max-width: 480px) {

  .instruction-overlay {

    padding: 10px;

  }


  .instruction-image {

    max-height:
      calc(
        100dvh - 90px
      );

  }


  .instruction-confirm-btn {

    width: 100%;

    min-width: 0;

    min-height: 52px;

    padding:
      0 16px;

    font-size: 18px;

  }


  .random-form {

    width:
      calc(
        100vw - 24px
      );

    gap: 10px;

    padding:
      10px 12px;

  }


  .participant-info {

    width: 100%;

    text-align: center;

    white-space: normal;

  }


  .study-error {

    width: 100%;

    text-align: center;

  }


  .rnd-btn {

    width: 100%;

  }


  .random-number.initial-hint {

    width: 88%;

    max-width: 88%;

    padding:
      8px 10px;

    font-size:
      clamp(
        19px,
        5.5vw,
        25px
      ) !important;

    line-height: 1.45;

  }


  .model-loading {

    width:
      min(
        92vw,
        440px
      );

  }

}



/* ==========================================================================
   LANDSCAPE PHONE

   Threshold rationale: max-height:520px reliably separates "phone in
   landscape" from "tablet in any orientation" across current common
   devices without hardcoding any specific model —
     phone landscape heights: ~375-430px (iPhone SE/mini/14/15,
       most Android phones)
     tablet landscape/portrait heights: 768px+ (iPad mini and up)
   A 520px cutoff sits safely in the gap between those two groups, so
   this rule targets "small phone, sideways" broadly rather than one
   device, and should keep working as new phone models ship.
   ========================================================================== */

@media
(max-height: 520px)
and
(orientation: landscape) {

  /*
    .random-form (top Start bar) and .random-box (center target) are
    positioned independently (absolute top:6% vs. grid-centered) and
    were only ever tuned for tall/portrait viewports. In a short
    landscape viewport they can collide or run off-screen. Shrink
    both and push the box down a bit so there is always daylight
    between them, on any phone.
  */

  .random-form {

    top: 2%;

    padding: 8px 12px;

    gap: 10px;

  }


  .rnd-btn {

    min-height: 38px;

    font-size: 14px;

  }


  .participant-info {

    font-size: 13px;

  }


  .random-box {

    width:
      min(
        70vw,
        480px
      );

    height:
      min(
        28vh,
        230px
      );

    margin-top: 12vh;

  }


  .instruction-overlay {

    padding:
      8px 14px;

  }


  .instruction-panel {

    max-height: 98vh;

    gap: 8px;

  }


  .instruction-image {

    max-height:
      calc(
        98vh - 62px
      );

  }


  .instruction-confirm-btn {

    min-height: 46px;

    font-size: 17px;

  }


  .random-number.initial-hint {

    font-size:
      clamp(
        18px,
        4.5vh,
        25px
      ) !important;

  }


  .random-box.countdown-mode::before {

    top: 10px;

    font-size: 18px;

  }


  .random-number.countdown {

    font-size:
      clamp(
        52px,
        13vmin,
        90px
      ) !important;

  }


  .model-loading {

    bottom: 5%;

  }

}