Spaces:
Running on Zero
Running on Zero
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet"> | |
| <style> | |
| /* ββ Reset & base βββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } | |
| :root { | |
| --bg: #0A0F1E; | |
| --surface: rgba(255,255,255,0.04); | |
| --surface-2: rgba(255,255,255,0.07); | |
| --border: rgba(255,255,255,0.08); | |
| --border-glow: rgba(124,58,237,0.5); | |
| --purple: #7C3AED; | |
| --purple-l: #A78BFA; | |
| --cyan: #06B6D4; | |
| --cyan-l: #67E8F9; | |
| --green: #10B981; | |
| --amber: #F59E0B; | |
| --red: #EF4444; | |
| --text: #F1F5F9; | |
| --muted: #94A3B8; | |
| --dim: #475569; | |
| --r: 18px; | |
| --r-sm: 10px; | |
| } | |
| html { scroll-behavior: smooth; } | |
| body { | |
| font-family: 'Inter', system-ui, sans-serif; | |
| background: var(--bg); | |
| color: var(--text); | |
| min-height: 100vh; | |
| overflow-x: hidden; | |
| background-image: | |
| radial-gradient(ellipse at 15% 40%, rgba(124,58,237,0.10) 0%, transparent 55%), | |
| radial-gradient(ellipse at 85% 15%, rgba(6,182,212,0.08) 0%, transparent 55%), | |
| radial-gradient(ellipse at 60% 90%, rgba(124,58,237,0.06) 0%, transparent 50%); | |
| } | |
| /* ββ Particles canvas βββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| #particles { | |
| position: fixed; inset: 0; | |
| pointer-events: none; z-index: 0; | |
| } | |
| /* ββ Layout βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| #app { | |
| position: relative; z-index: 1; | |
| max-width: 760px; | |
| margin: 0 auto; | |
| padding: 28px 20px 80px; | |
| display: flex; flex-direction: column; gap: 20px; | |
| } | |
| /* ββ Header β amphitheater hero βββββββββββββββββββββββββββββββββββββββββ */ | |
| .hero { | |
| position: relative; | |
| padding: 12px 0 0; | |
| animation: fadeUp .6s ease both; | |
| } | |
| .amphitheater { | |
| position: relative; z-index: 1; | |
| height: 380px; | |
| perspective: 800px; | |
| overflow: hidden; | |
| border-radius: var(--r); | |
| border: 1px solid var(--border); | |
| background: | |
| radial-gradient(ellipse 70% 45% at 50% -8%, rgba(167,139,250,.16) 0%, transparent 60%), | |
| radial-gradient(ellipse 60% 35% at 50% 112%, rgba(6,182,212,.12) 0%, transparent 65%), | |
| linear-gradient(180deg, #0B1126 0%, #0A0F1E 55%, #0C1226 100%); | |
| box-shadow: 0 8px 32px rgba(0,0,0,.45), 0 1px 0 rgba(255,255,255,.04) inset; | |
| } | |
| /* ceiling lights */ | |
| .amphi-light { | |
| position: absolute; z-index: 1; | |
| width: 4px; height: 4px; border-radius: 50%; | |
| background: #CFE9FF; | |
| box-shadow: 0 0 8px 2px rgba(167,139,250,.55); | |
| animation: twinkle 3.2s ease-in-out infinite; | |
| } | |
| .amphi-light:nth-of-type(2n) { | |
| box-shadow: 0 0 8px 2px rgba(103,232,249,.5); | |
| } | |
| /* ambient beam from above */ | |
| .amphi-beam { | |
| position: absolute; inset: 0; z-index: 1; pointer-events: none; | |
| background: radial-gradient(ellipse 55% 50% at 50% 0%, rgba(241,245,249,.07), transparent 70%); | |
| } | |
| /* curved seat rows receding into the distance */ | |
| .amphi-rows { | |
| position: absolute; inset: 0; z-index: 1; | |
| transform-style: preserve-3d; | |
| } | |
| .amphi-row { | |
| position: absolute; left: 50%; | |
| transform: translateX(-50%) rotateX(48deg); | |
| transform-origin: 50% 100%; | |
| border-radius: 50% 50% 0 0 / 90% 90% 0 0; | |
| background: | |
| linear-gradient(180deg, rgba(255,255,255,.09) 0%, transparent 35%), | |
| repeating-linear-gradient(90deg, | |
| #41322a 0, | |
| #41322a calc(var(--seat) - 6px), | |
| #221a15 calc(var(--seat) - 6px), | |
| #221a15 var(--seat)); | |
| box-shadow: 0 10px 18px rgba(0,0,0,.55); | |
| } | |
| .amphi-row:nth-child(1) { --seat: 18px; width: 54%; height: 16px; top: 30%; opacity: .45; } | |
| .amphi-row:nth-child(2) { --seat: 21px; width: 66%; height: 20px; top: 41%; opacity: .6; } | |
| .amphi-row:nth-child(3) { --seat: 24px; width: 80%; height: 24px; top: 52%; opacity: .75; } | |
| .amphi-row:nth-child(4) { --seat: 27px; width: 94%; height: 28px; top: 64%; opacity: .88; } | |
| .amphi-row:nth-child(5) { --seat: 30px; width: 110%; height: 32px; top: 77%; opacity: 1; } | |
| /* glowing stage + podium */ | |
| .amphi-stage { | |
| position: absolute; bottom: -8px; left: 50%; z-index: 2; | |
| transform: translateX(-50%); | |
| width: 60%; height: 74px; pointer-events: none; | |
| background: radial-gradient(ellipse at 50% 100%, rgba(6,182,212,.32), rgba(124,58,237,.16) 45%, transparent 72%); | |
| filter: blur(2px); | |
| } | |
| .amphi-podium { | |
| position: absolute; bottom: 18px; left: 50%; z-index: 2; | |
| transform: translateX(-50%); | |
| width: 130px; height: 26px; pointer-events: none; | |
| border-radius: 50%; | |
| background: radial-gradient(ellipse, rgba(103,232,249,.45), rgba(124,58,237,.22) 60%, transparent 78%); | |
| box-shadow: 0 0 30px rgba(6,182,212,.35); | |
| } | |
| /* ββ AI professor character βββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .professor { | |
| position: absolute; bottom: 36px; left: 50%; z-index: 3; | |
| width: 92px; margin-left: -46px; /* centered without transform β float animation owns transform */ | |
| cursor: pointer; | |
| animation: prof-float 3.6s ease-in-out infinite; | |
| filter: drop-shadow(0 10px 14px rgba(0,0,0,.5)); | |
| } | |
| .prof-antenna { | |
| width: 3px; height: 14px; margin: 0 auto; position: relative; | |
| background: linear-gradient(180deg, var(--cyan-l), var(--purple)); | |
| border-radius: 2px; | |
| } | |
| .prof-antenna::after { | |
| content: ''; position: absolute; top: -7px; left: 50%; | |
| transform: translateX(-50%); | |
| width: 9px; height: 9px; border-radius: 50%; | |
| background: var(--cyan-l); | |
| box-shadow: 0 0 10px 2px rgba(103,232,249,.8); | |
| animation: pulse 2.2s ease-in-out infinite; | |
| } | |
| .prof-head { | |
| width: 66px; height: 54px; margin: 0 auto; position: relative; | |
| display: flex; align-items: center; justify-content: center; gap: 10px; | |
| border-radius: 18px; | |
| background: linear-gradient(145deg, #262C4F 0%, #161B36 100%); | |
| border: 1.5px solid rgba(167,139,250,.45); | |
| box-shadow: 0 0 18px rgba(124,58,237,.25), inset 0 1px 0 rgba(255,255,255,.08); | |
| transition: transform .25s ease; | |
| } | |
| .professor:hover .prof-head { transform: rotate(-4deg); } | |
| .prof-eye { | |
| width: 17px; height: 19px; margin-top: -4px; | |
| border-radius: 50%; background: #EAF2FF; | |
| position: relative; overflow: hidden; | |
| animation: prof-blink 5.2s infinite; | |
| } | |
| .prof-pupil { | |
| position: absolute; left: 50%; top: 50%; | |
| width: 8px; height: 8px; margin: -4px 0 0 -4px; | |
| border-radius: 50%; background: #131A36; | |
| transition: transform 0.1s ease; | |
| } | |
| .prof-pupil::after { | |
| content: ''; position: absolute; top: 1px; left: 1.5px; | |
| width: 2.5px; height: 2.5px; border-radius: 50%; | |
| background: #fff; opacity: .9; | |
| } | |
| .prof-mouth { | |
| position: absolute; bottom: 8px; left: 50%; | |
| transform: translateX(-50%); | |
| width: 16px; height: 7px; | |
| border: 2px solid var(--cyan-l); border-top: none; | |
| border-radius: 0 0 14px 14px; | |
| opacity: .85; transition: width .2s, height .2s; | |
| } | |
| .professor:hover .prof-mouth { width: 22px; height: 10px; } | |
| .prof-body { | |
| width: 54px; height: 38px; margin: -3px auto 0; position: relative; | |
| border-radius: 14px 14px 16px 16px; | |
| background: linear-gradient(160deg, #2E2553 0%, #173A52 100%); | |
| border: 1.5px solid rgba(103,232,249,.35); | |
| box-shadow: inset 0 1px 0 rgba(255,255,255,.07); | |
| } | |
| .prof-chest { | |
| position: absolute; top: 50%; left: 50%; | |
| transform: translate(-50%, -50%); | |
| width: 12px; height: 12px; border-radius: 50%; | |
| background: radial-gradient(circle at 35% 35%, var(--cyan-l), var(--purple)); | |
| box-shadow: 0 0 12px rgba(103,232,249,.7); | |
| animation: pulse 2.8s ease-in-out infinite; | |
| } | |
| .prof-arm { | |
| position: absolute; top: 4px; | |
| width: 9px; height: 26px; border-radius: 6px; | |
| background: linear-gradient(180deg, #2E2553, #1D2348); | |
| border: 1.5px solid rgba(167,139,250,.3); | |
| transform-origin: top center; | |
| transition: transform .25s ease; | |
| } | |
| .prof-arm.left { left: -12px; transform: rotate(14deg); } | |
| .prof-arm.right { right: -12px; transform: rotate(-14deg); } | |
| .professor:hover .prof-arm.right { animation: prof-wave .8s ease-in-out infinite; } | |
| /* ββ Library wings β full-height public-library decor on both edges ββββ */ | |
| /* Positioned absolute (not fixed: Gradio ancestor transforms break fixed) | |
| and re-parented onto <body> by BRIDGE_JS, which also stretches the | |
| height to the full page and clones .lib-unit blocks to fill it. */ | |
| .library { | |
| position: absolute; top: 0; z-index: 0; | |
| /* stretch right up to the 760px centre column (20px breathing room) */ | |
| width: max(190px, calc((100vw - 800px) / 2)); | |
| height: 100vh; | |
| background: | |
| radial-gradient(ellipse 90% 16% at 50% -3%, rgba(167,139,250,.10), transparent 60%), | |
| linear-gradient(180deg, #0B1126 0%, #0A0F1E 55%, #0C1226 100%); | |
| overflow: hidden; | |
| /* no entrance animation: the BRIDGE_JS re-parent would restart it */ | |
| } | |
| .lib-unit { | |
| height: 950px; | |
| display: flex; flex-direction: column; justify-content: space-between; | |
| gap: 12px; padding: 26px 18px; | |
| } | |
| .library-left { left: 0; border-right: 1px solid var(--border); box-shadow: 18px 0 40px -20px rgba(0,0,0,.6); } | |
| .library-right { right: 0; border-left: 1px solid var(--border); box-shadow: -18px 0 40px -20px rgba(0,0,0,.6); } | |
| @media (max-width: 1180px) { .library { display: none; } } | |
| /* bookshelf rows β books bottom-align on a wood plank */ | |
| .lib-shelf { | |
| position: relative; height: 76px; flex-shrink: 0; | |
| display: flex; align-items: flex-end; gap: 4px; padding: 0 8px; | |
| border-bottom: 7px solid #3B2D23; | |
| box-shadow: 0 9px 12px -7px rgba(0,0,0,.6); | |
| overflow: hidden; /* shelves are over-filled; surplus books clip at the edge */ | |
| } | |
| .lib-shelf.pad-l { padding-left: 64px; } /* room for a robot on the left */ | |
| .lib-shelf.pad-r { padding-right: 64px; } /* room for a robot / ladder on the right */ | |
| .bk { | |
| display: block; flex-shrink: 0; | |
| width: 12px; height: var(--h, 40px); | |
| background: var(--c, #4C3D8F); | |
| border-radius: 2px 2px 0 0; | |
| box-shadow: inset -2px 0 0 rgba(0,0,0,.35), inset 0 2px 0 rgba(255,255,255,.18); | |
| } | |
| .bk.slim { width: 9px; } | |
| .bk.wide { width: 16px; } | |
| .bk.lean { | |
| transform: rotate(-9deg); | |
| transform-origin: bottom right; | |
| margin-left: -2px; | |
| } | |
| .b1 { --c: #7C3AED; } .b2 { --c: #A78BFA; } .b3 { --c: #06B6D4; } .b4 { --c: #67E8F9; } | |
| .b5 { --c: #E2E8F0; } .b6 { --c: #4C3D8F; } .b7 { --c: #1E6F8F; } .b8 { --c: #2E2553; } | |
| /* aisle β perspective corridor between two shelf walls */ | |
| .lib-aisle { | |
| position: relative; flex: 0 1 150px; min-height: 96px; | |
| border-radius: 10px; border: 1px solid var(--border); | |
| background: linear-gradient(180deg, #0A0F1E, #10172E); | |
| overflow: hidden; | |
| } | |
| .lib-aisle::before, .lib-aisle::after { | |
| content: ''; position: absolute; top: 0; bottom: 0; width: 50%; | |
| background: | |
| repeating-linear-gradient(0deg, rgba(59,45,35,.95) 0 5px, transparent 5px 26px), | |
| repeating-linear-gradient(90deg, | |
| #4C3D8F 0 6px, #06B6D4 6px 10px, #2E2553 10px 17px, | |
| #A78BFA 17px 21px, #1E2240 21px 30px); | |
| } | |
| .lib-aisle::before { left: 0; transform: perspective(240px) rotateY(50deg); transform-origin: left center; } | |
| .lib-aisle::after { right: 0; transform: perspective(240px) rotateY(-50deg); transform-origin: right center; } | |
| .aisle-end { /* glowing far end + floor */ | |
| position: absolute; inset: 0; pointer-events: none; | |
| background: | |
| radial-gradient(ellipse 26% 40% at 50% 46%, rgba(167,139,250,.30), transparent 70%), | |
| linear-gradient(180deg, transparent 58%, rgba(20,26,51,.9) 60%, #141A33 100%); | |
| } | |
| .aisle-bot { /* tiny robot deep in the corridor */ | |
| position: absolute; bottom: 26%; left: 50%; margin-left: -6px; | |
| width: 12px; height: 17px; border-radius: 4px 4px 3px 3px; | |
| background: linear-gradient(180deg, #262C4F 0 45%, #173A52 45% 100%); | |
| border: 1px solid rgba(167,139,250,.4); | |
| animation: aisle-walk 9s ease-in-out infinite; | |
| } | |
| .aisle-bot::before { /* visor */ | |
| content: ''; position: absolute; top: 4px; left: 2px; right: 2px; height: 3px; | |
| border-radius: 2px; background: rgba(234,242,255,.85); | |
| } | |
| /* tall section β shelf with room below for ladder / fetching robot */ | |
| .lib-tall { position: relative; flex: 0 1 200px; min-height: 150px; } | |
| .lib-tall .lib-shelf { position: absolute; top: 0; left: 0; right: 0; } | |
| .lib-ladder { | |
| position: absolute; bottom: 4px; right: 24px; | |
| width: 32px; height: 126px; | |
| transform: rotate(7deg); transform-origin: bottom center; | |
| border-left: 4px solid #4A372A; border-right: 4px solid #4A372A; | |
| background: repeating-linear-gradient(180deg, transparent 0 15px, #4A372A 15px 19px); | |
| border-radius: 3px; opacity: .9; | |
| } | |
| /* study desk β robot working behind it */ | |
| .lib-desk { position: relative; height: 92px; flex-shrink: 0; } | |
| .desk-table { position: absolute; bottom: 6px; left: 14%; right: 14%; height: 36px; } | |
| .desk-table::before { /* wood top */ | |
| content: ''; position: absolute; top: 0; left: 0; right: 0; height: 7px; | |
| background: linear-gradient(180deg, #4A372A, #33261D); | |
| border-radius: 3px; | |
| box-shadow: 0 3px 6px rgba(0,0,0,.45); | |
| } | |
| .desk-table::after { /* front panel */ | |
| content: ''; position: absolute; top: 7px; left: 7px; right: 7px; bottom: 0; | |
| background: linear-gradient(180deg, #2A2019, #1C1612); | |
| border-radius: 0 0 4px 4px; | |
| } | |
| .desk-screen { | |
| position: absolute; bottom: 48px; left: 58%; | |
| width: 17px; height: 12px; transform: skewX(-6deg); | |
| background: linear-gradient(180deg, #67E8F9, #0E7490); | |
| border-radius: 2px 2px 1px 1px; | |
| box-shadow: 0 0 10px rgba(103,232,249,.55); | |
| animation: pulse 1.7s ease-in-out infinite; | |
| } | |
| .desk-pile { position: absolute; bottom: 48px; left: 58%; width: 20px; } | |
| .desk-pile i { | |
| display: block; height: 5px; margin-top: 2px; border-radius: 2px; | |
| box-shadow: inset 0 1px 0 rgba(255,255,255,.25); | |
| } | |
| /* potted plant on a shelf */ | |
| .lib-plant { position: absolute; bottom: 0; right: 14px; width: 20px; height: 34px; } | |
| .lib-plant::before { | |
| content: ''; position: absolute; bottom: 9px; left: 50%; margin-left: -10px; | |
| width: 20px; height: 20px; | |
| background: radial-gradient(circle at 50% 90%, #10B981 0%, #0A7D5D 75%); | |
| border-radius: 50% 50% 46% 46% / 76% 76% 24% 24%; | |
| box-shadow: -5px 3px 0 -3px #0E9F77, 5px 3px 0 -3px #0E9F77; | |
| } | |
| .lib-plant::after { | |
| content: ''; position: absolute; bottom: 0; left: 50%; margin-left: -7px; | |
| width: 14px; height: 10px; | |
| background: linear-gradient(180deg, #4A372A, #33261D); | |
| clip-path: polygon(0 0, 100% 0, 82% 100%, 18% 100%); | |
| border-radius: 2px; | |
| } | |
| /* open floor at the bottom β patrol area */ | |
| .lib-floor { position: relative; flex: 1 0 96px; } | |
| /* ββ Mini robots ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .mini-bot { | |
| position: absolute; width: 44px; | |
| filter: drop-shadow(0 4px 6px rgba(0,0,0,.5)); | |
| } | |
| .mini-head { | |
| width: 28px; height: 21px; margin: 0 auto; position: relative; | |
| display: flex; align-items: center; justify-content: center; gap: 5px; | |
| border-radius: 9px; | |
| background: linear-gradient(145deg, #262C4F, #161B36); | |
| border: 1px solid rgba(167,139,250,.45); | |
| } | |
| .mini-head::before { /* antenna stem */ | |
| content: ''; position: absolute; top: -6px; left: 50%; margin-left: -1px; | |
| width: 2px; height: 6px; border-radius: 1px; | |
| background: var(--purple-l); | |
| } | |
| .mini-head::after { /* antenna tip */ | |
| content: ''; position: absolute; top: -10px; left: 50%; margin-left: -2.5px; | |
| width: 5px; height: 5px; border-radius: 50%; | |
| background: var(--cyan-l); | |
| box-shadow: 0 0 6px rgba(103,232,249,.8); | |
| } | |
| .mini-eye { width: 5px; height: 6px; border-radius: 50%; background: #EAF2FF; } | |
| .mini-body { | |
| width: 22px; height: 14px; margin: -2px auto 0; | |
| border-radius: 6px; | |
| background: linear-gradient(160deg, #2E2553, #173A52); | |
| border: 1px solid rgba(103,232,249,.35); | |
| } | |
| /* walking patrol along the floor, flipping at each end */ | |
| .bot-walker { bottom: 10px; animation: bot-walk 14s ease-in-out infinite; } | |
| .bot-carrier { bottom: 10px; animation: bot-walk 18s ease-in-out -6s infinite; } | |
| .bot-walker .mini-head, .bot-carrier .mini-head, | |
| .bot-worker .mini-head { animation: mini-bob .6s ease-in-out infinite; } | |
| /* stack of books carried in front */ | |
| .bot-stack { | |
| position: absolute; bottom: 2px; left: 50%; margin-left: -13px; | |
| width: 26px; z-index: 2; | |
| } | |
| .bot-stack i { | |
| display: block; height: 6px; margin-top: 2px; border-radius: 2px; | |
| box-shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.4); | |
| } | |
| /* sitting on a shelf, reading β gentle rocking, book held in front */ | |
| .bot-reader { | |
| bottom: 0; left: 10px; | |
| transform-origin: bottom center; | |
| animation: bot-read 3.4s ease-in-out infinite; | |
| } | |
| .bot-reader::after { | |
| content: ''; position: absolute; bottom: 1px; left: 50%; margin-left: -12px; | |
| width: 24px; height: 13px; | |
| background: linear-gradient(90deg, var(--purple) 0 47%, #E2E8F0 47% 53%, var(--cyan) 53% 100%); | |
| border-radius: 2px 2px 5px 5px; | |
| transform: perspective(40px) rotateX(28deg); | |
| box-shadow: 0 2px 4px rgba(0,0,0,.45); | |
| } | |
| /* dozing on a shelf β closed eyes, breathing pulse, floating zzz */ | |
| .bot-sleeper { | |
| bottom: 0; right: 12px; | |
| transform-origin: bottom center; | |
| animation: bot-sleep 3.8s ease-in-out infinite; | |
| } | |
| .bot-sleeper .mini-eye { height: 1.5px; border-radius: 1px; } | |
| .zz { | |
| position: absolute; bottom: 100%; left: 100%; | |
| font-size: 10px; font-weight: 800; line-height: 1; | |
| color: var(--cyan-l); opacity: 0; | |
| animation: zz-float 2.7s ease-out infinite; | |
| } | |
| .zz:nth-of-type(2) { animation-delay: .9s; font-size: 12px; } | |
| .zz:nth-of-type(3) { animation-delay: 1.8s; font-size: 14px; } | |
| /* climbing the ladder to fetch a book */ | |
| .bot-climber { right: 22px; bottom: 6px; animation: bot-climb 8s ease-in-out infinite; } | |
| /* on tiptoes, pulling a book down from the shelf above */ | |
| .bot-fetcher { | |
| left: 18px; bottom: 6px; | |
| transform-origin: bottom center; | |
| animation: bot-fetch 4.6s ease-in-out infinite; | |
| } | |
| .bot-fetcher::before { /* the coveted book */ | |
| content: ''; position: absolute; top: -13px; left: 50%; margin-left: -9px; | |
| width: 18px; height: 6px; border-radius: 2px; | |
| background: var(--purple); | |
| box-shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 3px rgba(0,0,0,.4); | |
| } | |
| /* seated at the desk, body hidden behind the front panel */ | |
| .bot-worker { left: 26%; bottom: 30px; } | |
| /* ββ Hero text overlay ββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .hero-overlay { | |
| position: absolute; top: 30px; left: 0; right: 0; z-index: 4; | |
| text-align: center; pointer-events: none; | |
| } | |
| .hero-title { | |
| font-size: clamp(2.2rem, 6vw, 3.4rem); | |
| font-weight: 900; line-height: 1; | |
| background: linear-gradient(135deg, var(--purple-l) 0%, var(--cyan-l) 100%); | |
| -webkit-background-clip: text; -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| letter-spacing: -1.5px; | |
| margin-bottom: 8px; | |
| filter: drop-shadow(0 4px 18px rgba(124,58,237,.35)); | |
| animation: fadeUp .7s .15s ease both; | |
| } | |
| .hero-sub { | |
| color: var(--muted); font-size: .98rem; font-weight: 400; | |
| letter-spacing: .01em; | |
| animation: fadeUp .7s .35s ease both; | |
| } | |
| /* ββ Card βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .card { | |
| background: rgba(10,15,30,0.65); | |
| backdrop-filter: blur(24px); | |
| -webkit-backdrop-filter: blur(24px); | |
| border: 1px solid var(--border); | |
| border-radius: var(--r); | |
| padding: 28px; | |
| box-shadow: 0 8px 32px rgba(0,0,0,.45), 0 1px 0 rgba(255,255,255,.04) inset; | |
| transition: border-color .25s; | |
| } | |
| .card:hover { border-color: rgba(255,255,255,.12); } | |
| /* ββ Buttons ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| button { cursor: pointer; font-family: inherit; font-size: .95rem; | |
| border: none; outline: none; transition: all .2s; } | |
| .btn-primary { | |
| display: inline-flex; align-items: center; justify-content: center; gap: 8px; | |
| padding: 12px 28px; border-radius: 50px; font-weight: 700; | |
| background: linear-gradient(135deg, var(--purple) 0%, var(--cyan) 100%); | |
| color: #fff; | |
| box-shadow: 0 4px 20px rgba(124,58,237,.35); | |
| } | |
| .btn-primary:hover:not(:disabled) { | |
| transform: translateY(-1px) scale(1.02); | |
| box-shadow: 0 6px 28px rgba(124,58,237,.5); | |
| } | |
| .btn-primary:active:not(:disabled) { transform: scale(.98); } | |
| .btn-primary:disabled { opacity: .4; cursor: not-allowed; } | |
| .btn-ghost { | |
| display: inline-flex; align-items: center; justify-content: center; gap: 6px; | |
| padding: 10px 22px; border-radius: 50px; font-weight: 600; | |
| background: transparent; color: var(--muted); | |
| border: 1px solid var(--border); | |
| } | |
| .btn-ghost:hover:not(:disabled) { | |
| background: var(--surface-2); color: var(--text); | |
| border-color: rgba(255,255,255,.2); | |
| } | |
| .btn-ghost:disabled { opacity: .35; cursor: not-allowed; } | |
| /* ββ Pill toggles βββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .toggle-group { display: flex; gap: 6px; } | |
| .pill { | |
| padding: 6px 16px; border-radius: 50px; font-size: .82rem; font-weight: 600; | |
| border: 1px solid var(--border); color: var(--muted); | |
| background: transparent; transition: all .18s; | |
| } | |
| .pill:hover { background: var(--surface-2); color: var(--text); border-color: rgba(255,255,255,.2); } | |
| .pill.active { | |
| background: linear-gradient(135deg, var(--purple), var(--cyan)); | |
| border-color: transparent; color: #fff; | |
| box-shadow: 0 2px 12px rgba(124,58,237,.4); | |
| } | |
| /* ββ Quiz controls row βββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .controls-row { | |
| display: flex; align-items: center; flex-wrap: wrap; gap: 12px; | |
| margin-bottom: 24px; | |
| } | |
| /* ββ Mode selector cards βββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .mode-selector { | |
| display: flex; gap: 10px; width: 100%; margin-bottom: 20px; | |
| } | |
| .mode-card { | |
| flex: 1; display: flex; align-items: center; gap: 12px; | |
| padding: 14px 16px; border-radius: var(--r-sm); | |
| border: 2px solid var(--border); | |
| background: var(--surface); | |
| cursor: pointer; transition: all .2s; text-align: left; | |
| font-family: inherit; | |
| } | |
| .mode-card:hover { border-color: rgba(255,255,255,.2); background: var(--surface-2); } | |
| .mode-card.selected { | |
| border-color: var(--purple); | |
| background: rgba(124,58,237,.12); | |
| box-shadow: 0 0 0 1px rgba(124,58,237,.3), 0 4px 16px rgba(124,58,237,.2); | |
| } | |
| .mode-card-icon { | |
| font-size: 1.5rem; flex-shrink: 0; | |
| width: 40px; height: 40px; | |
| border-radius: 10px; background: rgba(255,255,255,.06); | |
| display: flex; align-items: center; justify-content: center; | |
| transition: background .2s; | |
| } | |
| .mode-card.selected .mode-card-icon { background: rgba(124,58,237,.25); } | |
| .mode-card-body { flex: 1; } | |
| .mode-card-title { | |
| font-size: .92rem; font-weight: 700; color: var(--muted); | |
| margin-bottom: 2px; transition: color .2s; | |
| } | |
| .mode-card.selected .mode-card-title { color: var(--text); } | |
| .mode-card-desc { font-size: .75rem; color: var(--dim); line-height: 1.3; } | |
| .mode-card-check { | |
| width: 20px; height: 20px; border-radius: 50%; flex-shrink: 0; | |
| border: 2px solid var(--border); | |
| display: flex; align-items: center; justify-content: center; | |
| font-size: .7rem; color: transparent; | |
| transition: all .2s; | |
| } | |
| .mode-card.selected .mode-card-check { | |
| background: var(--purple); border-color: var(--purple); color: #fff; | |
| } | |
| .diff-label { font-size: .75rem; color: var(--dim); font-weight: 500; | |
| letter-spacing: .04em; margin-bottom: 4px; } | |
| /* ββ Score ring βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .score-wrap { position: relative; width: 56px; height: 56px; flex-shrink: 0; } | |
| .score-ring { width: 56px; height: 56px; } | |
| .score-label { | |
| position: absolute; inset: 0; | |
| display: flex; align-items: center; justify-content: center; | |
| font-size: .72rem; font-weight: 700; color: var(--text); | |
| letter-spacing: -.5px; | |
| } | |
| #score-arc { transition: stroke-dashoffset .6s cubic-bezier(.4,0,.2,1); } | |
| /* ββ Question card ββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .q-label { | |
| font-size: .72rem; font-weight: 700; letter-spacing: .1em; | |
| text-transform: uppercase; color: var(--purple-l); margin-bottom: 10px; | |
| } | |
| .q-text { | |
| font-size: 1.1rem; font-weight: 600; line-height: 1.55; | |
| color: var(--text); min-height: 3.2em; | |
| } | |
| .q-inner { | |
| background: rgba(124,58,237,.07); border: 1px solid rgba(124,58,237,.2); | |
| border-radius: var(--r-sm); padding: 18px 20px; margin-bottom: 20px; | |
| } | |
| /* ββ Answer area ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .answer-header { | |
| display: flex; justify-content: space-between; align-items: center; | |
| margin-bottom: 8px; | |
| } | |
| .answer-header label { font-size: .85rem; font-weight: 600; color: var(--muted); } | |
| .char-count { font-size: .78rem; color: var(--dim); font-variant-numeric: tabular-nums; } | |
| textarea.answer-input { | |
| width: 100%; resize: vertical; min-height: 110px; | |
| background: rgba(255,255,255,.04); border: 1px solid var(--border); | |
| border-radius: var(--r-sm); padding: 14px 16px; | |
| color: var(--text); font-family: inherit; font-size: .95rem; line-height: 1.5; | |
| outline: none; transition: border-color .2s, box-shadow .2s; | |
| } | |
| textarea.answer-input:focus { | |
| border-color: var(--purple); box-shadow: 0 0 0 3px rgba(124,58,237,.15); | |
| } | |
| textarea.answer-input::placeholder { color: var(--dim); } | |
| .answer-actions { | |
| display: flex; justify-content: flex-end; gap: 10px; margin-top: 14px; | |
| flex-wrap: wrap; | |
| } | |
| /* ββ No question prompt βββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .empty-state { | |
| text-align: center; padding: 32px 0; | |
| color: var(--muted); font-size: .95rem; | |
| } | |
| .empty-state p { margin-bottom: 18px; } | |
| /* ββ End session button βββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .end-row { margin-top: 20px; display: flex; justify-content: center; } | |
| /* ββ Spinner ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .spinner { | |
| width: 16px; height: 16px; border-radius: 50%; | |
| border: 2px solid rgba(255,255,255,.25); | |
| border-top-color: #fff; | |
| animation: spin .65s linear infinite; | |
| display: inline-block; flex-shrink: 0; | |
| } | |
| /* ββ Feedback card ββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .feedback-header { | |
| display: flex; align-items: center; gap: 12px; margin-bottom: 18px; | |
| } | |
| .verdict-badge { | |
| padding: 6px 18px; border-radius: 50px; | |
| font-size: .82rem; font-weight: 800; letter-spacing: .05em; | |
| text-transform: uppercase; flex-shrink: 0; | |
| animation: popIn .35s cubic-bezier(.34,1.56,.64,1) both; | |
| } | |
| .verdict-badge.correct { background: rgba(16,185,129,.18); border: 1px solid var(--green); color: #6EE7B7; } | |
| .verdict-badge.partial { background: rgba(245,158,11,.18); border: 1px solid var(--amber); color: #FCD34D; } | |
| .verdict-badge.incorrect { background: rgba(239,68,68,.18); border: 1px solid var(--red); color: #FCA5A5; } | |
| .feedback-body { | |
| font-size: .95rem; line-height: 1.7; color: var(--text); | |
| } | |
| .feedback-body .section { margin-bottom: 12px; } | |
| .feedback-body .section-num { | |
| font-size: .75rem; font-weight: 700; letter-spacing: .08em; | |
| text-transform: uppercase; color: var(--muted); display: block; | |
| margin-bottom: 4px; | |
| } | |
| .feedback-body .section-content { color: var(--text); } | |
| .feedback-raw { white-space: pre-wrap; } | |
| /* ββ Session image (modal) ββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| #modal-session-image { | |
| margin-bottom: 24px; padding: 18px; | |
| background: rgba(255,255,255,.04); | |
| border: 1px solid var(--border); | |
| border-radius: var(--r-sm); | |
| backdrop-filter: blur(12px); | |
| text-align: center; | |
| } | |
| .concept-image-title { | |
| font-size: .72rem; font-weight: 700; letter-spacing: .1em; | |
| text-transform: uppercase; color: var(--cyan-l); | |
| margin-bottom: 14px; text-align: left; | |
| } | |
| #session-image { | |
| width: 100%; max-width: 320px; display: inline-block; | |
| border-radius: var(--r-sm); border: 1px solid var(--border); | |
| box-shadow: 0 8px 24px rgba(0,0,0,.4); | |
| } | |
| .concept-image-caption { | |
| margin-top: 10px; font-size: .8rem; color: var(--muted); | |
| } | |
| /* ββ Collapsible source βββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| details.source-details { margin-top: 18px; } | |
| details.source-details summary { | |
| cursor: pointer; color: var(--dim); font-size: .82rem; font-weight: 600; | |
| letter-spacing: .03em; list-style: none; user-select: none; | |
| transition: color .2s; | |
| } | |
| details.source-details summary::before { content: 'βΆ '; font-size: .7em; } | |
| details.source-details[open] summary::before { content: 'βΌ '; } | |
| details.source-details summary:hover { color: var(--muted); } | |
| .source-text { | |
| margin-top: 10px; padding: 14px 16px; | |
| background: rgba(255,255,255,.03); border: 1px solid var(--border); | |
| border-radius: var(--r-sm); | |
| font-size: .82rem; line-height: 1.6; color: var(--muted); | |
| max-height: 180px; overflow-y: auto; | |
| } | |
| /* ββ Modal ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .modal-overlay { | |
| position: fixed; inset: 0; z-index: 100; | |
| background: rgba(0,0,0,.7); backdrop-filter: blur(8px); | |
| display: flex; align-items: center; justify-content: center; | |
| padding: 20px; | |
| animation: fadeIn .2s ease both; | |
| } | |
| .modal-card { | |
| background: rgba(15,20,40,.95); border: 1px solid rgba(124,58,237,.3); | |
| border-radius: 24px; padding: 40px 36px; | |
| max-width: 420px; width: 100%; text-align: center; | |
| box-shadow: 0 0 60px rgba(124,58,237,.25), 0 20px 60px rgba(0,0,0,.6); | |
| animation: popIn .4s cubic-bezier(.34,1.56,.64,1) both; | |
| } | |
| .modal-icon { font-size: 3.5rem; display: block; margin-bottom: 16px; | |
| filter: drop-shadow(0 0 12px rgba(124,58,237,.5)); } | |
| .modal-title { font-size: 1.7rem; font-weight: 800; margin-bottom: 20px; | |
| background: linear-gradient(135deg, var(--purple-l), var(--cyan-l)); | |
| -webkit-background-clip: text; -webkit-text-fill-color: transparent; | |
| background-clip: text; } | |
| .modal-score-big { | |
| font-size: 3.5rem; font-weight: 900; line-height: 1; | |
| background: linear-gradient(135deg, var(--purple-l), var(--cyan-l)); | |
| -webkit-background-clip: text; -webkit-text-fill-color: transparent; | |
| background-clip: text; margin-bottom: 8px; | |
| } | |
| .modal-score-label { color: var(--muted); font-size: .9rem; margin-bottom: 20px; } | |
| .modal-message { color: var(--muted); font-size: .95rem; line-height: 1.5; | |
| margin-bottom: 28px; } | |
| .modal-history { text-align: left; margin-bottom: 24px; } | |
| .modal-history-item { | |
| display: flex; align-items: flex-start; gap: 10px; | |
| padding: 8px 0; border-bottom: 1px solid var(--border); font-size: .85rem; | |
| } | |
| .modal-history-item:last-child { border-bottom: none; } | |
| .hist-badge { | |
| flex-shrink: 0; padding: 2px 10px; border-radius: 50px; font-size: .72rem; | |
| font-weight: 700; text-transform: uppercase; | |
| } | |
| .hist-badge.correct { background: rgba(16,185,129,.2); color: #6EE7B7; } | |
| .hist-badge.partial { background: rgba(245,158,11,.2); color: #FCD34D; } | |
| .hist-badge.incorrect { background: rgba(239,68,68,.2); color: #FCA5A5; } | |
| .hist-q { color: var(--muted); flex: 1; } | |
| /* ββ Loading overlay (inside card) βββββββββββββββββββββββββββββββββββββ */ | |
| .loading-msg { | |
| display: flex; align-items: center; justify-content: center; gap: 10px; | |
| padding: 14px; color: var(--muted); font-size: .9rem; | |
| } | |
| /* ββ Animations βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| @keyframes fadeUp { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } } | |
| @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } | |
| @keyframes popIn { from { opacity: 0; transform: scale(.8); } to { opacity: 1; transform: scale(1); } } | |
| @keyframes spin { to { transform: rotate(360deg); } } | |
| @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .4; } } | |
| @keyframes twinkle { 0%, 100% { opacity: .9; } 50% { opacity: .25; } } | |
| @keyframes prof-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-7px); } } | |
| @keyframes prof-blink { 0%, 90%, 100% { transform: scaleY(1); } 93% { transform: scaleY(.12); } 96% { transform: scaleY(1); } } | |
| @keyframes prof-wave { | |
| 0%, 100% { transform: rotate(-160deg); } | |
| 50% { transform: rotate(-115deg); } | |
| } | |
| @keyframes bot-walk { | |
| 0% { left: 10px; transform: scaleX(1); } | |
| 44% { left: calc(100% - 56px); transform: scaleX(1); } | |
| 50% { left: calc(100% - 56px); transform: scaleX(-1); } | |
| 94% { left: 10px; transform: scaleX(-1); } | |
| 100% { left: 10px; transform: scaleX(1); } | |
| } | |
| @keyframes bot-climb { | |
| 0%, 12% { transform: translate(0, 0); } | |
| 42%, 58% { transform: translate(-13px, -88px); } | |
| 88%, 100% { transform: translate(0, 0); } | |
| } | |
| @keyframes bot-fetch { 0%, 100% { transform: scaleY(1); } 45%, 60% { transform: scaleY(1.13); } } | |
| @keyframes aisle-walk { | |
| 0%, 100% { transform: translateX(-9px) scale(.92); } | |
| 50% { transform: translateX(9px) scale(1); } | |
| } | |
| @keyframes mini-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-1.5px); } } | |
| @keyframes bot-read { 0%, 100% { transform: rotate(-2deg); } 50% { transform: rotate(2.5deg); } } | |
| @keyframes bot-sleep { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.06); } } | |
| @keyframes zz-float { | |
| 0% { transform: translate(0, 0); opacity: 0; } | |
| 20% { opacity: .9; } | |
| 100% { transform: translate(10px, -24px); opacity: 0; } | |
| } | |
| .hidden { display: none ; } | |
| .fade-in-up { animation: fadeUp .4s ease both; } | |
| /* ββ MCQ options βββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .mcq-options { display: flex; flex-direction: column; gap: 10px; margin-bottom: 18px; } | |
| .mcq-btn { | |
| display: flex; align-items: center; gap: 14px; | |
| padding: 14px 18px; border-radius: var(--r-sm); | |
| background: var(--surface); border: 1px solid var(--border); | |
| color: var(--text); text-align: left; font-size: .95rem; font-weight: 500; | |
| width: 100%; transition: all .18s; | |
| } | |
| .mcq-btn:hover:not(:disabled) { | |
| background: var(--surface-2); border-color: rgba(255,255,255,.2); | |
| transform: translateX(4px); | |
| } | |
| .mcq-btn:disabled { cursor: default; } | |
| .mcq-btn.mcq-correct { background: rgba(16,185,129,.12); border-color: var(--green); } | |
| .mcq-btn.mcq-wrong { background: rgba(239,68,68,.12); border-color: var(--red); } | |
| .mcq-btn.mcq-neutral { opacity: .38; } | |
| .mcq-letter { | |
| flex-shrink: 0; width: 28px; height: 28px; border-radius: 50%; | |
| background: rgba(124,58,237,.2); border: 1px solid rgba(124,58,237,.3); | |
| display: flex; align-items: center; justify-content: center; | |
| font-size: .78rem; font-weight: 800; color: var(--purple-l); | |
| } | |
| .mcq-btn.mcq-correct .mcq-letter { background: rgba(16,185,129,.25); border-color: var(--green); color: #6EE7B7; } | |
| .mcq-btn.mcq-wrong .mcq-letter { background: rgba(239,68,68,.25); border-color: var(--red); color: #FCA5A5; } | |
| .mcq-text { flex: 1; line-height: 1.45; text-align: left; } | |
| /* ββ MCQ explanations ββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .mcq-explanations { display: flex; flex-direction: column; gap: 8px; margin-top: 18px; } | |
| .mcq-exp { | |
| display: flex; align-items: flex-start; gap: 10px; | |
| padding: 10px 14px; border-radius: var(--r-sm); | |
| font-size: .87rem; line-height: 1.5; | |
| } | |
| .exp-correct { background: rgba(16,185,129,.08); border: 1px solid rgba(16,185,129,.2); } | |
| .exp-wrong { background: rgba(239,68,68,.08); border: 1px solid rgba(239,68,68,.2); } | |
| .exp-neutral { background: var(--surface); border: 1px solid var(--border); } | |
| .mcq-exp-letter { | |
| flex-shrink: 0; width: 22px; height: 22px; border-radius: 50%; | |
| display: flex; align-items: center; justify-content: center; | |
| font-size: .72rem; font-weight: 800; | |
| } | |
| .exp-correct .mcq-exp-letter { background: rgba(16,185,129,.25); color: #6EE7B7; } | |
| .exp-wrong .mcq-exp-letter { background: rgba(239,68,68,.25); color: #FCA5A5; } | |
| .exp-neutral .mcq-exp-letter { background: rgba(255,255,255,.1); color: var(--muted); } | |
| .mcq-exp-text { color: var(--muted); flex: 1; } | |
| /* ββ Responsive βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| @media (max-width: 520px) { | |
| #app { padding: 20px 14px 60px; } | |
| .card { padding: 20px 18px; } | |
| .hero { padding: 8px 0 0; } | |
| .amphitheater { height: 300px; } | |
| .hero-overlay { top: 20px; } | |
| .hero-title { font-size: 2.2rem; } | |
| .controls-row { gap: 8px; } | |
| .answer-actions { flex-direction: column; } | |
| .answer-actions button { width: 100%; justify-content: center; } | |
| } | |
| </style> | |
| <canvas id="particles"></canvas> | |
| <!-- ββ Library wings β page-height decor flanking the app (decorative). | |
| BRIDGE_JS re-parents these onto <body>, sizes them to the full page | |
| and clones .lib-unit as many times as needed to reach the bottom. ββββ --> | |
| <div class="library library-left" aria-hidden="true"> | |
| <div class="lib-unit"> | |
| <div class="lib-shelf"> | |
| <i class="bk b2" style="--h:36px"></i><i class="bk b3" style="--h:50px"></i><i class="bk b1 slim" style="--h:56px"></i><i class="bk b6" style="--h:40px"></i> | |
| <i class="bk b1 lean" style="--h:34px"></i><i class="bk b6" style="--h:34px"></i><i class="bk b7 slim" style="--h:44px"></i><i class="bk b4" style="--h:46px"></i> | |
| <i class="bk b3 slim" style="--h:28px"></i><i class="bk b8 slim lean" style="--h:50px"></i><i class="bk b3" style="--h:52px"></i><i class="bk b4" style="--h:40px"></i> | |
| <i class="bk b1" style="--h:38px"></i><i class="bk b6" style="--h:28px"></i><i class="bk b7" style="--h:30px"></i><i class="bk b4" style="--h:36px"></i> | |
| <i class="bk b8 slim" style="--h:56px"></i><i class="bk b7" style="--h:34px"></i><i class="bk b6" style="--h:48px"></i><i class="bk b2 slim" style="--h:30px"></i> | |
| <i class="bk b8" style="--h:36px"></i><i class="bk b4 slim" style="--h:38px"></i><i class="bk b2" style="--h:34px"></i><i class="bk b7" style="--h:56px"></i> | |
| <i class="bk b6 slim" style="--h:46px"></i><i class="bk b5 slim" style="--h:32px"></i><i class="bk b4" style="--h:56px"></i><i class="bk b7 slim" style="--h:34px"></i> | |
| <i class="bk b6" style="--h:52px"></i><i class="bk b8 lean" style="--h:54px"></i> | |
| </div> | |
| <div class="lib-shelf pad-l"> | |
| <i class="bk b6" style="--h:30px"></i><i class="bk b2 wide" style="--h:46px"></i><i class="bk b7" style="--h:48px"></i><i class="bk b4" style="--h:56px"></i> | |
| <i class="bk b7 lean" style="--h:36px"></i><i class="bk b6" style="--h:36px"></i><i class="bk b7" style="--h:56px"></i><i class="bk b5" style="--h:34px"></i> | |
| <i class="bk b2" style="--h:30px"></i><i class="bk b8 lean" style="--h:30px"></i><i class="bk b2 slim" style="--h:40px"></i><i class="bk b6" style="--h:40px"></i> | |
| <i class="bk b5 wide" style="--h:44px"></i><i class="bk b3 wide" style="--h:54px"></i><i class="bk b1 slim" style="--h:30px"></i><i class="bk b6 slim" style="--h:52px"></i> | |
| <i class="bk b7" style="--h:36px"></i><i class="bk b4" style="--h:28px"></i><i class="bk b7 wide" style="--h:36px"></i><i class="bk b5 slim" style="--h:44px"></i> | |
| <i class="bk b8 slim" style="--h:54px"></i><i class="bk b6" style="--h:34px"></i><i class="bk b2" style="--h:32px"></i><i class="bk b6 wide" style="--h:56px"></i> | |
| <i class="bk b5 wide lean" style="--h:46px"></i><i class="bk b1" style="--h:38px"></i><i class="bk b8 slim" style="--h:34px"></i><i class="bk b1" style="--h:46px"></i> | |
| <div class="mini-bot bot-reader"><div class="mini-head"><span class="mini-eye"></span><span class="mini-eye"></span></div><div class="mini-body"></div></div> | |
| </div> | |
| <div class="lib-aisle"><div class="aisle-end"></div><span class="aisle-bot"></span></div> | |
| <div class="lib-tall"> | |
| <div class="lib-shelf pad-r"> | |
| <i class="bk b2" style="--h:42px"></i><i class="bk b8" style="--h:52px"></i><i class="bk b5 slim" style="--h:32px"></i><i class="bk b7" style="--h:44px"></i> | |
| <i class="bk b2" style="--h:54px"></i><i class="bk b3 wide" style="--h:52px"></i><i class="bk b7 slim" style="--h:50px"></i><i class="bk b3" style="--h:48px"></i> | |
| <i class="bk b7" style="--h:56px"></i><i class="bk b5 lean" style="--h:34px"></i><i class="bk b3" style="--h:44px"></i><i class="bk b2" style="--h:28px"></i> | |
| <i class="bk b1 slim" style="--h:28px"></i><i class="bk b3" style="--h:28px"></i><i class="bk b8 lean" style="--h:44px"></i><i class="bk b6" style="--h:44px"></i> | |
| <i class="bk b2 slim" style="--h:56px"></i><i class="bk b6" style="--h:34px"></i><i class="bk b8" style="--h:40px"></i><i class="bk b2 lean" style="--h:48px"></i> | |
| <i class="bk b5" style="--h:54px"></i><i class="bk b7" style="--h:48px"></i><i class="bk b6" style="--h:40px"></i><i class="bk b7" style="--h:54px"></i> | |
| <i class="bk b1 lean" style="--h:34px"></i><i class="bk b3" style="--h:36px"></i><i class="bk b5" style="--h:56px"></i><i class="bk b1" style="--h:54px"></i> | |
| </div> | |
| <div class="lib-ladder"></div> | |
| <div class="mini-bot bot-climber"><div class="mini-head"><span class="mini-eye"></span><span class="mini-eye"></span></div><div class="mini-body"></div></div> | |
| </div> | |
| <div class="lib-desk"> | |
| <div class="mini-bot bot-worker"><div class="mini-head"><span class="mini-eye"></span><span class="mini-eye"></span></div><div class="mini-body"></div></div> | |
| <div class="desk-table"></div> | |
| <div class="desk-screen"></div> | |
| </div> | |
| <div class="lib-floor"> | |
| <div class="mini-bot bot-walker"><div class="mini-head"><span class="mini-eye"></span><span class="mini-eye"></span></div><div class="mini-body"></div></div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="library library-right" aria-hidden="true"> | |
| <div class="lib-unit"> | |
| <div class="lib-shelf pad-r"> | |
| <i class="bk b2" style="--h:44px"></i><i class="bk b8" style="--h:30px"></i><i class="bk b7 slim" style="--h:32px"></i><i class="bk b4" style="--h:34px"></i> | |
| <i class="bk b8 lean" style="--h:28px"></i><i class="bk b1 wide" style="--h:36px"></i><i class="bk b8 slim" style="--h:36px"></i><i class="bk b4 slim" style="--h:50px"></i> | |
| <i class="bk b8" style="--h:50px"></i><i class="bk b4 lean" style="--h:36px"></i><i class="bk b1" style="--h:44px"></i><i class="bk b2 slim" style="--h:28px"></i> | |
| <i class="bk b1" style="--h:44px"></i><i class="bk b8" style="--h:28px"></i><i class="bk b5 lean" style="--h:32px"></i><i class="bk b1 slim" style="--h:34px"></i> | |
| <i class="bk b5" style="--h:56px"></i><i class="bk b6" style="--h:46px"></i><i class="bk b1 slim" style="--h:40px"></i><i class="bk b7 lean" style="--h:44px"></i> | |
| <i class="bk b3" style="--h:50px"></i><i class="bk b4" style="--h:40px"></i><i class="bk b2 slim" style="--h:36px"></i><i class="bk b5" style="--h:52px"></i> | |
| <i class="bk b1" style="--h:46px"></i><i class="bk b2" style="--h:34px"></i><i class="bk b6" style="--h:56px"></i><i class="bk b3 wide" style="--h:56px"></i> | |
| <div class="mini-bot bot-sleeper"><div class="mini-head"><span class="mini-eye"></span><span class="mini-eye"></span></div><div class="mini-body"></div><span class="zz">z</span><span class="zz">z</span><span class="zz">z</span></div> | |
| </div> | |
| <div class="lib-shelf" style="padding-right:46px"> | |
| <i class="bk b4" style="--h:32px"></i><i class="bk b5 slim" style="--h:50px"></i><i class="bk b3 slim" style="--h:52px"></i><i class="bk b7" style="--h:48px"></i> | |
| <i class="bk b8" style="--h:56px"></i><i class="bk b2" style="--h:56px"></i><i class="bk b1 slim" style="--h:32px"></i><i class="bk b4" style="--h:34px"></i> | |
| <i class="bk b7" style="--h:48px"></i><i class="bk b6 wide lean" style="--h:44px"></i><i class="bk b8" style="--h:48px"></i><i class="bk b4 slim" style="--h:28px"></i> | |
| <i class="bk b1" style="--h:32px"></i><i class="bk b7 wide" style="--h:32px"></i><i class="bk b6 lean" style="--h:50px"></i><i class="bk b1" style="--h:56px"></i> | |
| <i class="bk b7 wide" style="--h:44px"></i><i class="bk b1 slim" style="--h:46px"></i><i class="bk b6" style="--h:32px"></i><i class="bk b1" style="--h:56px"></i> | |
| <i class="bk b8" style="--h:38px"></i><i class="bk b2 slim" style="--h:48px"></i><i class="bk b1" style="--h:44px"></i><i class="bk b8" style="--h:46px"></i> | |
| <i class="bk b6 lean" style="--h:56px"></i><i class="bk b2 wide" style="--h:52px"></i><i class="bk b3 wide" style="--h:28px"></i><i class="bk b2 slim" style="--h:38px"></i> | |
| <div class="lib-plant"></div> | |
| </div> | |
| <div class="lib-aisle"><div class="aisle-end"></div><span class="aisle-bot" style="animation-delay:-4s"></span></div> | |
| <div class="lib-tall"> | |
| <div class="lib-shelf pad-l" style="justify-content:flex-end"> | |
| <i class="bk b7 slim" style="--h:54px"></i><i class="bk b6 slim" style="--h:36px"></i><i class="bk b2 slim" style="--h:30px"></i><i class="bk b5 wide" style="--h:54px"></i> | |
| <i class="bk b4" style="--h:54px"></i><i class="bk b3" style="--h:52px"></i><i class="bk b8" style="--h:28px"></i><i class="bk b6" style="--h:38px"></i> | |
| <i class="bk b3 wide" style="--h:52px"></i><i class="bk b4 lean" style="--h:44px"></i><i class="bk b8" style="--h:28px"></i><i class="bk b1 wide" style="--h:36px"></i> | |
| <i class="bk b3" style="--h:36px"></i><i class="bk b1" style="--h:40px"></i><i class="bk b4 slim lean" style="--h:38px"></i><i class="bk b6" style="--h:56px"></i> | |
| <i class="bk b5" style="--h:28px"></i><i class="bk b7" style="--h:44px"></i><i class="bk b8" style="--h:50px"></i><i class="bk b6 slim lean" style="--h:34px"></i> | |
| <i class="bk b1 wide" style="--h:56px"></i><i class="bk b4 slim" style="--h:48px"></i><i class="bk b8" style="--h:56px"></i><i class="bk b3" style="--h:48px"></i> | |
| <i class="bk b5 lean" style="--h:50px"></i><i class="bk b2" style="--h:48px"></i><i class="bk b5 slim" style="--h:56px"></i><i class="bk b2 slim" style="--h:36px"></i> | |
| </div> | |
| <div class="mini-bot bot-fetcher"><div class="mini-head"><span class="mini-eye"></span><span class="mini-eye"></span></div><div class="mini-body"></div></div> | |
| </div> | |
| <div class="lib-desk"> | |
| <div class="mini-bot bot-worker"><div class="mini-head"><span class="mini-eye"></span><span class="mini-eye"></span></div><div class="mini-body"></div></div> | |
| <div class="desk-table"></div> | |
| <div class="desk-pile"><i style="background:#06B6D4"></i><i style="background:#A78BFA"></i><i style="background:#E2E8F0"></i></div> | |
| </div> | |
| <div class="lib-floor"> | |
| <div class="mini-bot bot-carrier"> | |
| <div class="bot-stack"><i style="background:#7C3AED"></i><i style="background:#67E8F9"></i><i style="background:#E2E8F0"></i></div> | |
| <div class="mini-head"><span class="mini-eye"></span><span class="mini-eye"></span></div><div class="mini-body"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="app"> | |
| <!-- Hero β cinematic amphitheater with AI professor --> | |
| <header class="hero"> | |
| <!-- Library wing β left (decorative) --> | |
| <div class="amphitheater" id="amphitheater"> | |
| <div class="amphi-beam"></div> | |
| <!-- ceiling lights --> | |
| <span class="amphi-light" style="left:9%; top:9%; animation-delay:0s"></span> | |
| <span class="amphi-light" style="left:21%; top:5%; animation-delay:.7s"></span> | |
| <span class="amphi-light" style="left:36%; top:11%; animation-delay:1.4s"></span> | |
| <span class="amphi-light" style="left:51%; top:4%; animation-delay:.3s"></span> | |
| <span class="amphi-light" style="left:65%; top:10%; animation-delay:1.9s"></span> | |
| <span class="amphi-light" style="left:79%; top:6%; animation-delay:1.1s"></span> | |
| <span class="amphi-light" style="left:91%; top:12%; animation-delay:.5s"></span> | |
| <!-- curved seat rows, far β near --> | |
| <div class="amphi-rows"> | |
| <div class="amphi-row"></div> | |
| <div class="amphi-row"></div> | |
| <div class="amphi-row"></div> | |
| <div class="amphi-row"></div> | |
| <div class="amphi-row"></div> | |
| </div> | |
| <!-- glowing stage --> | |
| <div class="amphi-stage"></div> | |
| <div class="amphi-podium"></div> | |
| <!-- AI professor (eyes wired to the mouse in BRIDGE_JS) --> | |
| <div class="professor" id="professor" title="Your AI professor"> | |
| <div class="prof-antenna"></div> | |
| <div class="prof-head"> | |
| <div class="prof-eye"><div class="prof-pupil"></div></div> | |
| <div class="prof-eye"><div class="prof-pupil"></div></div> | |
| <div class="prof-mouth"></div> | |
| </div> | |
| <div class="prof-body"> | |
| <div class="prof-arm left"></div> | |
| <div class="prof-arm right"></div> | |
| <div class="prof-chest"></div> | |
| </div> | |
| </div> | |
| <!-- floating text overlay --> | |
| <div class="hero-overlay"> | |
| <h1 class="hero-title">PaperProf</h1> | |
| <p class="hero-sub">Upload your course. Get quizzed by AI.</p> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- ββ Quiz card ββββββββββββββββββββββββββββββββββββββββββββββββββββββ --> | |
| <div class="card hidden fade-in-up" id="quiz-card" style="animation-delay:.1s"> | |
| <!-- Mode selector --> | |
| <div class="mode-selector"> | |
| <button class="mode-card selected" id="mode-open-btn"> | |
| <div class="mode-card-icon">βοΈ</div> | |
| <div class="mode-card-body"> | |
| <div class="mode-card-title">Open Question</div> | |
| <div class="mode-card-desc">Write a free-form answer</div> | |
| </div> | |
| <div class="mode-card-check">β</div> | |
| </button> | |
| <button class="mode-card" id="mode-mcq-btn"> | |
| <div class="mode-card-icon">π―</div> | |
| <div class="mode-card-body"> | |
| <div class="mode-card-title">Multiple Choice</div> | |
| <div class="mode-card-desc">Pick the correct answer</div> | |
| </div> | |
| <div class="mode-card-check">β</div> | |
| </button> | |
| </div> | |
| <!-- Controls row --> | |
| <div class="controls-row"> | |
| <!-- Score ring --> | |
| <div class="score-wrap" style="margin-left:auto" title="Score"> | |
| <svg class="score-ring" viewBox="0 0 56 56"> | |
| <circle cx="28" cy="28" r="22" fill="none" | |
| stroke="rgba(255,255,255,0.08)" stroke-width="4"/> | |
| <circle id="score-arc" cx="28" cy="28" r="22" fill="none" | |
| stroke="url(#scoreGrad)" stroke-width="4" stroke-linecap="round" | |
| stroke-dasharray="138.2" stroke-dashoffset="138.2" | |
| transform="rotate(-90 28 28)"/> | |
| <defs> | |
| <linearGradient id="scoreGrad" x1="0%" y1="0%" x2="100%" y2="0%"> | |
| <stop offset="0%" stop-color="#7C3AED"/> | |
| <stop offset="100%" stop-color="#06B6D4"/> | |
| </linearGradient> | |
| </defs> | |
| </svg> | |
| <div class="score-label" id="score-label">β</div> | |
| </div> | |
| </div> | |
| <!-- Empty state (before first question) --> | |
| <div class="empty-state" id="empty-state"> | |
| <p>Ready! Click to generate your first question.</p> | |
| <button class="btn-primary" id="start-btn"> | |
| New Question | |
| </button> | |
| </div> | |
| <!-- Question + answer (shown after first question) --> | |
| <div class="hidden" id="question-area"> | |
| <div class="q-inner"> | |
| <div class="q-label">Question</div> | |
| <p class="q-text" id="q-text"></p> | |
| <div class="loading-msg hidden" id="q-loading"> | |
| <span class="spinner"></span> | |
| <span id="q-loading-msg">Generating questionβ¦</span> | |
| </div> | |
| </div> | |
| <!-- MCQ options (shown in MCQ mode) --> | |
| <div class="mcq-options hidden" id="mcq-options"> | |
| <button class="mcq-btn" id="mcq-a"><span class="mcq-letter">A</span><span class="mcq-text" id="mcq-text-a"></span></button> | |
| <button class="mcq-btn" id="mcq-b"><span class="mcq-letter">B</span><span class="mcq-text" id="mcq-text-b"></span></button> | |
| <button class="mcq-btn" id="mcq-c"><span class="mcq-letter">C</span><span class="mcq-text" id="mcq-text-c"></span></button> | |
| <button class="mcq-btn" id="mcq-d"><span class="mcq-letter">D</span><span class="mcq-text" id="mcq-text-d"></span></button> | |
| </div> | |
| <!-- Open-Q answer (hidden in MCQ mode) --> | |
| <div id="answer-wrapper"> | |
| <div class="answer-header"> | |
| <label for="answer-input">Your Answer</label> | |
| <span class="char-count" id="char-count">0 chars</span> | |
| </div> | |
| <textarea class="answer-input" id="answer-input" | |
| placeholder="Type your answer hereβ¦" rows="4"></textarea> | |
| </div> | |
| <div class="answer-actions"> | |
| <button class="btn-ghost" id="new-q-btn">βΊ New Question</button> | |
| <button class="btn-primary" id="submit-btn" disabled> | |
| <span id="submit-btn-text">Submit Answer</span> | |
| <span class="spinner hidden" id="submit-spinner"></span> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="end-row"> | |
| <button class="btn-ghost hidden" id="end-btn" style="font-size:.82rem;padding:7px 18px"> | |
| End Session | |
| </button> | |
| </div> | |
| </div> | |
| <!-- ββ Feedback card βββββββββββββββββββββββββββββββββββββββββββββββββββ --> | |
| <div class="card hidden" id="feedback-card"> | |
| <div class="feedback-header"> | |
| <div class="verdict-badge" id="verdict-badge"></div> | |
| <span style="font-size:.85rem;color:var(--muted);font-weight:600">Feedback</span> | |
| </div> | |
| <div class="feedback-body" id="feedback-body"></div> | |
| <div class="mcq-explanations hidden" id="mcq-explanations"></div> | |
| </div> | |
| </div> | |
| <!-- ββ Session modal βββββββββββββββββββββββββββββββββββββββββββββββββββββ --> | |
| <div class="modal-overlay hidden" id="modal"> | |
| <div class="modal-card"> | |
| <span class="modal-icon">π</span> | |
| <h2 class="modal-title">Session Complete</h2> | |
| <div class="modal-score-big" id="modal-score-big">β</div> | |
| <div class="modal-score-label" id="modal-score-label">questions answered</div> | |
| <p class="modal-message" id="modal-message"></p> | |
| <div class="modal-history hidden" id="modal-history"></div> | |
| <div class="loading-msg hidden" id="modal-image-loading"> | |
| <span class="spinner"></span> Preparing your reward⦠| |
| </div> | |
| <div class="hidden" id="modal-session-image"> | |
| <div class="concept-image-title">Your Reward</div> | |
| <img id="session-image" alt="An encouraging illustration" /> | |
| <p class="concept-image-caption">A little encouragement from your AI professor π</p> | |
| </div> | |
| <button class="btn-primary" id="modal-close" style="width:100%;justify-content:center"> | |
| Study Again | |
| </button> | |
| </div> | |
| </div> | |
| <script> | |
| // Intentionally empty β browsers never execute <script> tags injected via | |
| // innerHTML (gr.HTML), so ALL page logic (quiz flow, particles, professor | |
| // eye tracking) lives in BRIDGE_JS in app.py, injected via demo.load(js=...). | |
| void 0; | |
| </script> | |