Spaces:
Running
Running
| /* βββ palette βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| * Maharashtra Warli-art palette: gerua (geru / ΰ€ΰ₯ΰ€°ΰ₯, ochre-red earth pigment | |
| * traditional to Warli wall paintings) + warm cream + kumkum highlight. | |
| * Aligned to the SVG header (`warli-strip.svg`) which uses #c34a19 β #9f320f | |
| * gradient on #fff8ec for the dancers/sun/microphones. | |
| * | |
| * Cream paper #FAF3E7 | |
| * Ivory card #F2E8D3 | |
| * Gerua (Warli red-ochre) #C34A19 β was #E07A1F (too saffron-yellow) | |
| * Gerua dark #9F320F β matches SVG gradient endpoint | |
| * Kumkum (deep red) #8E2E2E | |
| * Ink brown #2E1D10 | |
| * Muted cocoa #8C6E56 | |
| * Warli white #FFF8EC β matches SVG #fff8ec | |
| * Sage (success) #6B8B4E | |
| */ | |
| :root { | |
| --bg: #FAF3E7; | |
| --card: #F2E8D3; | |
| --card-border: #D9C9A7; | |
| --accent: #C34A19; /* gerua β earth-pigment red, authentic Warli */ | |
| --accent-dark: #9F320F; /* deep gerua, matches SVG gradient bottom */ | |
| --accent-soft: #C34A1922; | |
| --red: #8E2E2E; | |
| --ink: #2E1D10; | |
| --muted: #8C6E56; | |
| --good: #6B8B4E; | |
| --bad: #A63A3A; | |
| --warli: #FFF8EC; | |
| font-family: "Inter", -apple-system, "Segoe UI", sans-serif; | |
| } | |
| * { box-sizing: border-box; } | |
| html, body { | |
| margin: 0; | |
| background: var(--bg); | |
| color: var(--ink); | |
| min-height: 100vh; | |
| line-height: 1.5; | |
| } | |
| /* βββ typography ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| * Yatra One: festival/display feel for title + ornamentals | |
| * Tiro Devanagari Marathi: elegant serif for Devanagari body text | |
| */ | |
| .font-display { font-family: "Yatra One", "Tiro Devanagari Marathi", serif; } | |
| .font-devanagari { | |
| font-family: "Inter", "Tiro Devanagari Marathi", "Noto Sans Devanagari", serif; | |
| font-weight: 400; | |
| } | |
| /* βββ warli border strip βββββββββββββββββββββββββββββββββββββββββββββββββ | |
| * Tribal art band β dancers, hut, deer, microphones, sun motifs in white on | |
| * saffron. Originals are 2172Γ154 PNG; we display at fixed pixel height and | |
| * stretch horizontally to the viewport (object-fit: cover). | |
| */ | |
| .warli-strip { | |
| width: 100%; | |
| margin-top: 24px; | |
| display: flex; | |
| justify-content: center; | |
| overflow: hidden; | |
| } | |
| .warli-strip img { | |
| /* Natural aspect (2172Γ154 β 14:1). width:100% fills the viewport up to | |
| * max-width; past that the strip caps and cream gutters appear on either | |
| * side. No object-fit cropping, no distortion, triangle borders always | |
| * visible. */ | |
| width: 100%; | |
| height: auto; | |
| max-width: 1600px; | |
| display: block; | |
| } | |
| .warli-strip--bottom { | |
| margin-top: 24px; | |
| /* No rotation β the SVG already has triangle borders on BOTH the top and | |
| * bottom edges of the strip, so the same image works for both header and | |
| * footer. Rotating 180Β° would have flipped figures upside-down. */ | |
| } | |
| /* βββ layout ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| main { | |
| max-width: 860px; | |
| margin: 0 auto; | |
| padding: 40px 24px 80px; | |
| } | |
| header { | |
| text-align: center; | |
| margin-bottom: 32px; | |
| } | |
| header h1 { | |
| font-family: "Yatra One", "Tiro Devanagari Marathi", serif; | |
| font-size: 38px; | |
| margin: 0 0 6px; | |
| color: var(--red); | |
| letter-spacing: 0; | |
| } | |
| header .sub { | |
| margin: 0; | |
| color: var(--muted); | |
| font-size: 14px; | |
| } | |
| header .namaste { | |
| font-family: "Tiro Devanagari Marathi", serif; | |
| font-size: 18px; | |
| color: var(--accent-dark); | |
| margin-bottom: 8px; | |
| display: block; | |
| } | |
| .card { | |
| background: var(--card); | |
| border: 1px solid var(--card-border); | |
| border-radius: 14px; | |
| padding: 18px 20px; | |
| margin-bottom: 16px; | |
| box-shadow: 0 1px 2px rgba(46, 29, 16, 0.04); | |
| } | |
| .status { | |
| font-family: ui-monospace, SFMono-Regular, Menlo, monospace; | |
| font-size: 13px; | |
| color: var(--muted); | |
| padding: 10px 14px; | |
| } | |
| .status.ready { color: var(--good); } | |
| .status.error { color: var(--bad); } | |
| .model-gate { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| gap: 16px; | |
| border-left: 3px solid var(--accent); | |
| } | |
| .model-gate-text { font-size: 14px; color: var(--ink); line-height: 1.7; } | |
| .model-gate-text strong { color: var(--red); } | |
| .model-gate-sub { color: var(--muted); font-size: 12px; display: block; margin-top: 4px; } | |
| .model-gate-variant { | |
| display: block; | |
| font-size: 13px; | |
| cursor: pointer; | |
| padding: 2px 0; | |
| } | |
| .model-gate-variant input[type=radio] { accent-color: var(--accent); margin-right: 6px; } | |
| .model-gate button { flex-shrink: 0; } | |
| label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 6px; } | |
| /* Row that puts the textarea label and the Transliterate utility button on | |
| the same line, label flush left and button flush right. */ | |
| .text-label-row { | |
| display: flex; | |
| align-items: baseline; | |
| justify-content: space-between; | |
| gap: 12px; | |
| margin-bottom: 6px; | |
| } | |
| .text-label-row label { margin: 0; } | |
| .text-tool { | |
| background: transparent; | |
| color: var(--accent-dark); | |
| border: 1px solid var(--card-border); | |
| border-radius: 999px; | |
| padding: 3px 10px; | |
| font-size: 12px; | |
| font-family: "Inter", "Tiro Devanagari Marathi", sans-serif; | |
| cursor: pointer; | |
| transition: background 120ms, color 120ms, border-color 120ms; | |
| } | |
| .text-tool:hover { | |
| background: var(--accent-soft); | |
| border-color: var(--accent); | |
| color: var(--accent-dark); | |
| } | |
| textarea { | |
| width: 100%; | |
| background: var(--warli); | |
| color: var(--ink); | |
| border: 1px solid var(--card-border); | |
| border-radius: 10px; | |
| padding: 12px 14px; | |
| font-size: 19px; | |
| font-family: "Inter", "Tiro Devanagari Marathi", "Noto Sans Devanagari", serif; | |
| line-height: 1.55; | |
| resize: vertical; | |
| } | |
| textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; } | |
| .examples { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 6px; align-items: center; } | |
| .examples-label { color: var(--muted); font-size: 12px; margin-right: 4px; } | |
| .chip { | |
| background: transparent; | |
| color: var(--ink); | |
| border: 1px solid var(--card-border); | |
| border-radius: 999px; | |
| padding: 4px 10px; | |
| font-size: 13px; | |
| font-family: "Inter", "Tiro Devanagari Marathi", "Noto Sans Devanagari", serif; | |
| cursor: pointer; | |
| transition: background 120ms, color 120ms, border-color 120ms; | |
| } | |
| .chip:hover { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-dark); } | |
| .controls { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr auto; | |
| gap: 14px; | |
| align-items: end; | |
| margin-top: 14px; | |
| } | |
| .controls select, .controls input[type=range] { | |
| width: 100%; | |
| background: var(--warli); | |
| color: var(--ink); | |
| border: 1px solid var(--card-border); | |
| border-radius: 8px; | |
| padding: 7px 10px; | |
| } | |
| .controls input[type=range] { | |
| accent-color: var(--accent); | |
| padding: 4px 0; | |
| } | |
| .speed-control { margin-bottom: 0; } | |
| .speed-control-row { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: baseline; | |
| margin-bottom: 6px; | |
| font-size: 13px; | |
| color: var(--muted); | |
| } | |
| .speed-control-row #speed-val { | |
| font-family: ui-monospace, SFMono-Regular, Menlo, monospace; | |
| font-size: 12px; | |
| color: var(--accent-dark); | |
| font-variant-numeric: tabular-nums; | |
| } | |
| button.primary { | |
| background: var(--accent); | |
| color: #fff; | |
| border: none; | |
| border-radius: 8px; | |
| padding: 9px 20px; | |
| font-weight: 600; | |
| cursor: pointer; | |
| font-size: 14px; | |
| font-family: "Inter", "Tiro Devanagari Marathi", sans-serif; | |
| } | |
| button.primary:hover { background: var(--accent-dark); } | |
| button.primary:disabled { opacity: 0.45; cursor: default; } | |
| .ab-test { margin-top: 10px; } | |
| /* βββ audio output area ββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* βββ fused player: play/pause button + seekable waveform + time βββββββ */ | |
| .player { | |
| display: grid; | |
| grid-template-columns: 48px 1fr; | |
| gap: 12px; | |
| align-items: center; | |
| background: var(--warli); | |
| border: 1px solid var(--card-border); | |
| border-radius: 10px; | |
| padding: 10px 12px; | |
| margin-bottom: 14px; | |
| } | |
| .playpause { | |
| width: 44px; | |
| height: 44px; | |
| border-radius: 50%; | |
| background: var(--accent); | |
| color: #fff; | |
| border: none; | |
| font-size: 18px; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| line-height: 1; | |
| padding: 0; | |
| transition: background 120ms; | |
| } | |
| .playpause:hover { background: var(--accent-dark); } | |
| .playpause.playing { font-size: 16px; } | |
| .player-main { | |
| position: relative; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 2px; | |
| } | |
| .waveform { | |
| width: 100%; | |
| height: 56px; | |
| background: transparent; | |
| cursor: pointer; | |
| display: block; | |
| } | |
| .waveform:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-radius: 4px; } | |
| .player-time { | |
| display: flex; | |
| justify-content: space-between; | |
| font-family: ui-monospace, SFMono-Regular, Menlo, monospace; | |
| font-size: 11px; | |
| color: var(--muted); | |
| font-feature-settings: "tnum"; | |
| padding: 0 2px; | |
| } | |
| /* βββ compact transcript (default view) β Marathi text with per-word hl ββ */ | |
| .transcript-compact { | |
| font-family: "Inter", "Tiro Devanagari Marathi", "Noto Sans Devanagari", serif; | |
| font-size: 24px; | |
| line-height: 1.7; | |
| padding: 14px 16px; | |
| border: 1px solid var(--card-border); | |
| border-radius: 10px; | |
| background: var(--warli); | |
| color: var(--ink); | |
| min-height: 60px; | |
| } | |
| .transcript-compact .word { | |
| display: inline-block; | |
| padding: 1px 4px; | |
| border-radius: 4px; | |
| cursor: pointer; | |
| transition: background-color 150ms ease, color 150ms ease; | |
| } | |
| .transcript-compact .word:hover { background: var(--accent-soft); } | |
| .transcript-compact .word:focus { outline: 2px solid var(--accent); outline-offset: -1px; } | |
| .transcript-compact .word.active { | |
| background: var(--accent); | |
| color: #fff; | |
| } | |
| .transcript-compact .word.past { color: var(--muted); } | |
| /* βββ expandable per-word detail (IPA + timing) βββββββββββββββββββββββββ */ | |
| .transcript-details { | |
| margin-top: 10px; | |
| } | |
| .transcript-details > summary { | |
| cursor: pointer; | |
| color: var(--muted); | |
| font-size: 12px; | |
| padding: 4px 6px; | |
| user-select: none; | |
| } | |
| .transcript-details > summary:hover { color: var(--accent-dark); } | |
| .transcript-details[open] > summary { margin-bottom: 8px; } | |
| /* βββ side-by-side Devanagari / IPA / timing columns βββββββββββββββββββ */ | |
| .sidebyside { | |
| display: grid; | |
| grid-template-columns: minmax(140px, 1.2fr) minmax(160px, 1.8fr) 2fr; | |
| gap: 0; | |
| border: 1px solid var(--card-border); | |
| border-radius: 10px; | |
| overflow: hidden; | |
| background: var(--warli); | |
| } | |
| .sidebyside .col-head { | |
| font-family: "Yatra One", serif; | |
| font-size: 13px; | |
| color: var(--red); | |
| padding: 8px 12px; | |
| border-bottom: 1px solid var(--card-border); | |
| background: #EFE2C5; | |
| letter-spacing: 0.02em; | |
| } | |
| .sidebyside .row { | |
| display: contents; | |
| } | |
| .sidebyside .cell { | |
| padding: 10px 12px; | |
| border-bottom: 1px solid #E8DBBF; | |
| display: flex; | |
| align-items: center; | |
| transition: background-color 180ms ease; | |
| } | |
| .sidebyside .row.active .cell { background: var(--accent-soft); } | |
| .sidebyside .row.past .cell { color: var(--muted); } | |
| .sidebyside .row:last-child .cell { border-bottom: none; } | |
| .cell.devanagari { | |
| font-family: "Inter", "Tiro Devanagari Marathi", "Noto Sans Devanagari", serif; | |
| font-size: 22px; | |
| font-weight: 500; | |
| color: var(--ink); | |
| } | |
| .sidebyside .row.active .cell.devanagari { color: var(--red); } | |
| .cell.ipa { | |
| font-family: ui-monospace, SFMono-Regular, Menlo, monospace; | |
| font-size: 14px; | |
| color: var(--accent-dark); | |
| } | |
| .cell.timing { | |
| position: relative; | |
| font-family: ui-monospace, SFMono-Regular, Menlo, monospace; | |
| font-size: 12px; | |
| color: var(--muted); | |
| padding: 10px 12px; | |
| } | |
| .cell.timing .bar { | |
| position: absolute; | |
| left: 10px; | |
| right: 10px; | |
| bottom: 6px; | |
| height: 4px; | |
| background: #E8DBBF; | |
| border-radius: 2px; | |
| overflow: hidden; | |
| } | |
| .cell.timing .bar-fill { | |
| height: 100%; | |
| background: var(--accent); | |
| border-radius: 2px; | |
| transform-origin: left center; | |
| transition: transform 80ms linear; | |
| } | |
| .sidebyside .row.past .cell.timing .bar-fill { | |
| background: var(--muted); | |
| transform: scaleX(1); | |
| } | |
| .cell.timing .range { | |
| font-feature-settings: "tnum"; | |
| margin-right: 10px; | |
| } | |
| /* βββ Marathi facts sidebar ββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .facts { | |
| background: #EFE2C5; | |
| border-left: 3px solid var(--accent); | |
| padding: 10px 14px; | |
| border-radius: 6px; | |
| font-size: 13px; | |
| color: var(--ink); | |
| margin-top: 14px; | |
| line-height: 1.55; | |
| } | |
| .facts strong { color: var(--red); font-weight: 600; } | |
| .facts .ipa-inline { | |
| font-family: ui-monospace, SFMono-Regular, Menlo, monospace; | |
| color: var(--accent-dark); | |
| } | |
| /* βββ misc βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .details { margin-top: 12px; } | |
| .details summary { cursor: pointer; color: var(--muted); font-size: 12px; } | |
| .phonemes, .word-timings { | |
| font-family: ui-monospace, SFMono-Regular, Menlo, monospace; | |
| font-size: 12px; | |
| color: var(--muted); | |
| white-space: pre-wrap; | |
| margin: 8px 0 0; | |
| padding: 10px; | |
| background: #EAE0C5; | |
| border-radius: 6px; | |
| max-height: 220px; | |
| overflow: auto; | |
| } | |
| footer { | |
| margin-top: 40px; | |
| color: var(--muted); | |
| font-size: 12px; | |
| text-align: center; | |
| } | |
| footer a, | |
| header p a { color: var(--accent-dark); text-decoration: underline; } | |
| footer a:hover, | |
| header p a:hover { color: var(--red); } | |
| /* download button on the player β small circular, sits to the right of the waveform */ | |
| .audio-dl-btn { | |
| flex: 0 0 auto; | |
| width: 36px; | |
| height: 36px; | |
| border-radius: 50%; | |
| border: 1px solid var(--card-border); | |
| background: var(--warli); | |
| color: var(--accent-dark); | |
| font-size: 16px; | |
| line-height: 34px; | |
| text-align: center; | |
| text-decoration: none; | |
| cursor: pointer; | |
| transition: background 120ms, color 120ms, border-color 120ms; | |
| align-self: center; | |
| margin-left: 8px; | |
| } | |
| .audio-dl-btn:hover { | |
| background: var(--accent-soft); | |
| border-color: var(--accent); | |
| color: var(--accent); | |
| } | |
| /* voice picker: "π§ Reference clip" link sits above the <select>, right-aligned */ | |
| .voice-control { margin-bottom: 0; } | |
| .voice-control-row { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: baseline; | |
| gap: 8px; | |
| margin-bottom: 4px; | |
| } | |
| .voice-ref-link { | |
| font-size: 11px; | |
| color: var(--accent-dark); | |
| text-decoration: none; | |
| border-bottom: 1px dotted var(--accent-soft); | |
| cursor: pointer; | |
| transition: color 120ms, border-color 120ms; | |
| } | |
| .voice-ref-link:hover { | |
| color: var(--accent); | |
| border-bottom-color: var(--accent); | |
| } | |
| /* performance metrics card β 3-column grid below the output transcript */ | |
| .metrics-card { | |
| margin-top: 18px; | |
| } | |
| .metrics-header { | |
| font-size: 11px; | |
| letter-spacing: 1.5px; | |
| text-transform: uppercase; | |
| color: var(--muted); | |
| margin-bottom: 12px; | |
| font-weight: 600; | |
| } | |
| .metrics-grid { | |
| display: grid; | |
| grid-template-columns: repeat(3, 1fr); | |
| gap: 12px; | |
| } | |
| @media (max-width: 600px) { | |
| .metrics-grid { grid-template-columns: 1fr; } | |
| } | |
| .metric { | |
| background: var(--warli); | |
| border: 1px solid var(--card-border); | |
| border-radius: 8px; | |
| padding: 12px 14px; | |
| } | |
| .metric-highlight { | |
| background: var(--accent-soft); | |
| border-color: var(--accent); | |
| } | |
| .metric-label { | |
| font-size: 12px; | |
| color: var(--muted); | |
| margin-bottom: 6px; | |
| } | |
| .metric-value { | |
| font-size: 28px; | |
| font-weight: 600; | |
| color: var(--ink); | |
| line-height: 1; | |
| font-variant-numeric: tabular-nums; | |
| } | |
| .metric-highlight .metric-value { color: var(--accent-dark); } | |
| .metric-unit { | |
| font-size: 14px; | |
| font-weight: 400; | |
| color: var(--muted); | |
| margin-left: 3px; | |
| } | |
| .metric-context { | |
| font-size: 10px; | |
| color: var(--muted); | |
| margin-top: 6px; | |
| letter-spacing: 0.2px; | |
| } | |