:root { --bg: #0b1a10; --surface: #122318; --surface2: #1a3326; --surface3: #203d2f; --gold: #c9a84c; --gold-light: #e2c97e; --gold-dim: #8a6f2e; --green: #2e7d52; --green-light: #3da368; --text: #e8e0d0; --text-dim: #9e9688; --sub: #e05252; /* substitution */ --del: #e09c52; /* deletion */ --ins: #5282e0; /* insertion */ --ok: #52c97b; /* correct */ --border: #2a4a38; --radius: 12px; --radius-lg: 20px; } *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } html { font-size: 16px; } body { font-family: 'Cairo', 'Amiri', sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; direction: rtl; background-image: radial-gradient(ellipse at 20% 0%, rgba(46,125,82,.18) 0%, transparent 55%), radial-gradient(ellipse at 80% 100%, rgba(201,168,76,.10) 0%, transparent 55%); } /* ── Scrollbar ── */ ::-webkit-scrollbar { width: 6px; } ::-webkit-scrollbar-track { background: var(--surface); } ::-webkit-scrollbar-thumb { background: var(--gold-dim); border-radius: 3px; } /* ── Geometric border utility ── */ .geo-border { border: 1px solid var(--border); position: relative; } .geo-border::before, .geo-border::after { content: '❖'; position: absolute; color: var(--gold-dim); font-size: .75rem; line-height: 1; } .geo-border::before { top: -9px; right: 12px; } .geo-border::after { bottom: -9px; left: 12px; } /* ── Animations ── */ @keyframes fadeUp { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } } @keyframes shimmer { 0% { background-position: -200% center; } 100% { background-position: 200% center; } } @keyframes pulse-ring { 0% { box-shadow: 0 0 0 0 rgba(201,168,76,.35); } 70% { box-shadow: 0 0 0 10px rgba(201,168,76,0); } 100% { box-shadow: 0 0 0 0 rgba(201,168,76,0); } } @keyframes spin { to { transform: rotate(360deg); } } .animate-fade-up { animation: fadeUp .45s ease both; } /* ── Layout ── */ .app { max-width: 860px; margin: 0 auto; padding: 2rem 1.25rem 4rem; display: flex; flex-direction: column; gap: 1.75rem; } /* ── Header ── */ .header { text-align: center; padding: 2rem 1rem 1.5rem; position: relative; } .header-ornament { font-size: 1.1rem; color: var(--gold-dim); letter-spacing: .25em; margin-bottom: .6rem; } .header h1 { font-family: 'Amiri', serif; font-size: 2.4rem; font-weight: 700; color: var(--gold-light); line-height: 1.3; text-shadow: 0 2px 20px rgba(201,168,76,.3); } .header-sub { color: var(--text-dim); font-size: .95rem; margin-top: .5rem; } .header-line { display: flex; align-items: center; gap: .75rem; margin: 1rem auto 0; width: fit-content; } .header-line span { height: 1px; width: 60px; background: linear-gradient(90deg, transparent, var(--gold-dim)); } .header-line span:last-child { background: linear-gradient(270deg, transparent, var(--gold-dim)); } .header-line .star { color: var(--gold); font-size: 1rem; } /* ── Input card ── */ .input-card { background: var(--surface); border-radius: var(--radius-lg); padding: 1.5rem; border: 1px solid var(--border); box-shadow: 0 4px 24px rgba(0,0,0,.3); } .input-label { font-size: .85rem; color: var(--gold); font-weight: 600; letter-spacing: .05em; margin-bottom: .75rem; display: flex; align-items: center; gap: .5rem; } .input-label svg { width: 16px; height: 16px; flex-shrink: 0; } .verse-textarea { width: 100%; min-height: 120px; background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius); color: var(--text); font-family: 'Amiri Quran', 'Amiri', serif; font-size: 1.55rem; line-height: 2; padding: 1rem 1.1rem; resize: vertical; outline: none; transition: border-color .2s, box-shadow .2s; direction: rtl; } .verse-textarea::placeholder { color: var(--text-dim); font-size: 1.2rem; line-height: 2.2; } .verse-textarea:focus { border-color: var(--gold-dim); box-shadow: 0 0 0 3px rgba(201,168,76,.12); } /* ── Quick examples ── */ .examples { margin-top: .85rem; display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; } .examples-label { font-size: .78rem; color: var(--text-dim); flex-shrink: 0; } .example-chip { background: var(--surface3); border: 1px solid var(--border); border-radius: 20px; padding: .25rem .75rem; font-size: .8rem; font-family: 'Amiri', serif; color: var(--text-dim); cursor: pointer; transition: all .18s; white-space: nowrap; } .example-chip:hover { background: var(--surface2); border-color: var(--gold-dim); color: var(--gold-light); } /* ── Actions ── */ .actions { display: flex; gap: .75rem; margin-top: 1rem; justify-content: flex-start; } .btn-validate { display: flex; align-items: center; gap: .55rem; background: linear-gradient(135deg, #2e7d52, #1f5e3b); border: 1px solid var(--green); color: #fff; font-family: 'Cairo', sans-serif; font-weight: 700; font-size: 1rem; padding: .7rem 1.75rem; border-radius: var(--radius); cursor: pointer; transition: all .2s; letter-spacing: .02em; } .btn-validate:hover:not(:disabled) { background: linear-gradient(135deg, #3da368, #2e7d52); box-shadow: 0 4px 16px rgba(46,125,82,.4); animation: pulse-ring 1.2s ease-out; } .btn-validate:disabled { opacity: .55; cursor: not-allowed; } .btn-validate .spinner { width: 18px; height: 18px; border: 2px solid rgba(255,255,255,.3); border-top-color: #fff; border-radius: 50%; animation: spin .7s linear infinite; } .btn-clear { background: transparent; border: 1px solid var(--border); color: var(--text-dim); font-family: 'Cairo', sans-serif; font-size: .9rem; padding: .7rem 1.2rem; border-radius: var(--radius); cursor: pointer; transition: all .2s; } .btn-clear:hover { border-color: var(--text-dim); color: var(--text); } /* ── Result card ── */ .result-card { background: var(--surface); border-radius: var(--radius-lg); border: 1px solid var(--border); overflow: hidden; box-shadow: 0 4px 24px rgba(0,0,0,.3); } /* ── Verdict banner ── */ .verdict-banner { padding: 1.25rem 1.5rem; display: flex; align-items: center; gap: 1rem; } .verdict-banner.correct { background: linear-gradient(135deg, rgba(82,201,123,.15), rgba(46,125,82,.08)); border-bottom: 1px solid rgba(82,201,123,.25); } .verdict-banner.incorrect { background: linear-gradient(135deg, rgba(224,82,82,.12), rgba(150,50,50,.06)); border-bottom: 1px solid rgba(224,82,82,.2); } .verdict-icon { font-size: 2.5rem; line-height: 1; flex-shrink: 0; } .verdict-text h2 { font-family: 'Amiri', serif; font-size: 1.5rem; font-weight: 700; } .verdict-banner.correct .verdict-text h2 { color: var(--ok); } .verdict-banner.incorrect .verdict-text h2 { color: var(--sub); } .verdict-text p { font-size: .85rem; color: var(--text-dim); margin-top: .2rem; } /* ── Verse info ── */ .verse-info { display: flex; gap: .75rem; padding: 1rem 1.5rem; border-bottom: 1px solid var(--border); flex-wrap: wrap; } .verse-badge { background: var(--surface2); border: 1px solid var(--border); border-radius: 8px; padding: .4rem .9rem; font-size: .82rem; display: flex; flex-direction: column; align-items: center; gap: .1rem; } .verse-badge .badge-label { color: var(--text-dim); font-size: .7rem; text-transform: uppercase; letter-spacing: .05em; } .verse-badge .badge-value { color: var(--gold-light); font-weight: 600; font-family: 'Amiri', serif; } .match-type-badge { border-radius: 20px; padding: .3rem .85rem; font-size: .75rem; font-weight: 700; letter-spacing: .04em; align-self: center; margin-right: auto; } .match-exact { background: rgba(82,201,123,.15); color: var(--ok); border: 1px solid rgba(82,201,123,.3); } .match-lemma { background: rgba(82,130,224,.15); color: #82a8e8; border: 1px solid rgba(82,130,224,.3); } .match-root { background: rgba(201,168,76,.15); color: var(--gold); border: 1px solid rgba(201,168,76,.3); } .match-fuzzy { background: rgba(224,156,82,.15); color: #e8a85a; border: 1px solid rgba(224,156,82,.3); } /* ── WER gauge ── */ .wer-section { padding: 1rem 1.5rem; border-bottom: 1px solid var(--border); } .wer-header { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: .5rem; } .wer-label { font-size: .8rem; color: var(--text-dim); } .wer-value { font-size: .9rem; font-weight: 700; } .wer-bar-bg { height: 8px; background: var(--surface3); border-radius: 4px; overflow: hidden; } .wer-bar-fill { height: 100%; border-radius: 4px; transition: width .6s cubic-bezier(.4,0,.2,1); } .wer-ok { background: linear-gradient(90deg, #52c97b, #3da368); } .wer-low { background: linear-gradient(90deg, #c9c952, #a3a33d); } .wer-mid { background: linear-gradient(90deg, #e09c52, #b07030); } .wer-high { background: linear-gradient(90deg, #e05252, #b03030); } /* ── Mistakes list ── */ .mistakes-section { padding: 1rem 1.5rem; border-bottom: 1px solid var(--border); } .section-title { font-size: .82rem; color: var(--text-dim); font-weight: 600; letter-spacing: .06em; margin-bottom: .85rem; display: flex; align-items: center; gap: .5rem; } .section-title::after { content: ''; flex: 1; height: 1px; background: var(--border); } .mistakes-list { display: flex; flex-direction: column; gap: .55rem; } .mistake-row { display: flex; align-items: flex-start; gap: .75rem; padding: .65rem .9rem; border-radius: var(--radius); font-size: .92rem; font-family: 'Amiri', serif; line-height: 1.6; animation: fadeUp .3s ease both; } .mistake-row.sub { background: rgba(224,82,82,.08); border: 1px solid rgba(224,82,82,.2); } .mistake-row.del { background: rgba(224,156,82,.08); border: 1px solid rgba(224,156,82,.2); } .mistake-row.ins { background: rgba(82,130,224,.08); border: 1px solid rgba(82,130,224,.2); } .mistake-tag { font-size: .65rem; font-weight: 700; letter-spacing: .06em; padding: .2rem .55rem; border-radius: 10px; flex-shrink: 0; margin-top: .2rem; font-family: 'Cairo', sans-serif; } .mistake-row.sub .mistake-tag { background: rgba(224,82,82,.2); color: var(--sub); } .mistake-row.del .mistake-tag { background: rgba(224,156,82,.2); color: var(--del); } .mistake-row.ins .mistake-tag { background: rgba(82,130,224,.2); color: var(--ins); } .mistake-text { color: var(--text); } .mistake-text .word-wrong { color: var(--sub); font-weight: 700; } .mistake-text .word-correct { color: var(--ok); font-weight: 700; } .mistake-text .word-missing { color: var(--del); font-weight: 700; } .mistake-text .word-extra { color: var(--ins); font-weight: 700; } .arrow { color: var(--text-dim); margin: 0 .3rem; } .no-mistakes { text-align: center; padding: .75rem; color: var(--ok); font-size: .9rem; } /* ── Correct verse display ── */ .verse-display { padding: 1.25rem 1.5rem; } .correct-verse { background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.2rem 1.5rem; text-align: center; position: relative; overflow: hidden; } .correct-verse::before { content: ''; position: absolute; inset: 0; background: linear-gradient(135deg, rgba(201,168,76,.04), transparent); pointer-events: none; } .correct-verse-text { font-family: 'Amiri Quran', 'Amiri', serif; font-size: 1.75rem; line-height: 2.2; color: var(--gold-light); direction: rtl; } .correct-verse-meta { margin-top: .5rem; font-size: .8rem; color: var(--text-dim); } /* ── Stats row ── */ .stats-row { display: flex; gap: .5rem; padding: 0 1.5rem 1.25rem; flex-wrap: wrap; } .stat-chip { background: var(--surface2); border: 1px solid var(--border); border-radius: 8px; padding: .35rem .8rem; font-size: .78rem; color: var(--text-dim); display: flex; gap: .3rem; align-items: center; } .stat-chip span { color: var(--gold); font-weight: 600; } /* ── Empty state ── */ .empty-state { text-align: center; padding: 3rem 1rem; color: var(--text-dim); } .empty-icon { font-size: 3.5rem; margin-bottom: 1rem; opacity: .4; } .empty-state p { font-family: 'Amiri', serif; font-size: 1.1rem; } /* ── Footer ── */ .footer { text-align: center; color: var(--text-dim); font-size: .78rem; padding-top: 1rem; border-top: 1px solid var(--border); } /* ── Tashkeel section ── */ .tashkeel-section { padding: 0 1.5rem 1rem; } .tashkeel-list { display: flex; flex-direction: column; gap: .4rem; } .tashkeel-row { display: flex; gap: .75rem; align-items: baseline; padding: .4rem .8rem; background: rgba(201,168,76,.06); border: 1px solid rgba(201,168,76,.2); border-radius: 8px; font-size: .87rem; } .tashkeel-word { color: var(--gold-light); font-family: 'Amiri', serif; font-weight: 700; } .tashkeel-detail { color: var(--text-dim); } .tashkeel-detail em { font-style: normal; color: var(--text); } /* ── Multi-verse accordion ── */ .verses-accord-list { display: flex; flex-direction: column; gap: .4rem; padding: 0 1.5rem 1rem; } .verse-accord { border-radius: var(--radius); overflow: hidden; animation: fadeUp .35s ease both; } .verse-accord.accord-ok { border: 1px solid rgba(82,201,123,.2); } .verse-accord.accord-err { border: 1px solid rgba(224,82,82,.2); } .accord-header { width: 100%; display: flex; align-items: center; gap: .6rem; padding: .65rem 1rem; background: var(--surface2); border: none; cursor: pointer; text-align: right; direction: rtl; color: var(--text); font-family: 'Cairo', sans-serif; font-size: .92rem; transition: background .15s; } .accord-header:hover { background: var(--surface3); } .accord-ok .accord-header { background: rgba(82,201,123,.06); } .accord-err .accord-header { background: rgba(224,82,82,.06); } .accord-icon { font-size: .9rem; flex-shrink: 0; } .accord-key { font-weight: 700; color: var(--gold); min-width: 50px; } .accord-surah { color: var(--text-dim); font-size: .82rem; } .accord-wer { font-size: .78rem; font-weight: 600; margin-right: auto; } .accord-chevron { margin-right: auto; color: var(--text-dim); display: flex; } .accord-body { padding: .75rem 1rem; background: var(--surface); border-top: 1px solid var(--border); } /* ── Responsive ── */ @media (max-width: 600px) { .header h1 { font-size: 1.8rem; } .verse-textarea { font-size: 1.3rem; } .correct-verse-text { font-size: 1.4rem; } .verse-info { gap: .5rem; } .verses-accord-list { padding: 0 .75rem 1rem; } }