1338 lines
66 KiB
PHP
1338 lines
66 KiB
PHP
@extends('frontend.layouts.app')
|
||
@php
|
||
$__izleLabel = $anime->type === 'movie' ? 'Filmi İzle' : 'İzle';
|
||
$__animeSeoTitle = $anime->title . ' ' . $__izleLabel . ' - Türkçe Altyazılı | Animexe';
|
||
$__animeSeoDesc = $anime->title . ' ' . $__izleLabel
|
||
. ' — Türkçe altyazılı ve dublajlı, ücretsiz HD kalitede Animexe\'de.'
|
||
. ($anime->description ? ' ' . Str::limit(strip_tags($anime->description), 80) : '');
|
||
$__animeOgImg = $anime->bannerUrl ?? $anime->coverUrl ?? url('/logo.jpg');
|
||
$__animeCanon = rtrim(\App\Models\Setting::get('seo_canonical_domain', config('app.url')), '/') . route('anime.show', $anime->slug, false);
|
||
$__animeType = $anime->type === 'movie' ? 'Movie' : 'TVSeries';
|
||
$__animeGenres = $anime->genres->pluck('name')->implode(', ');
|
||
$__domain = rtrim(\App\Models\Setting::get('seo_canonical_domain', config('app.url')), '/');
|
||
|
||
// Auto-FAQ: DB verilerinden kurallı sorular
|
||
$__faqItems = [];
|
||
$__faqItems[] = [
|
||
'q' => $anime->title . ' nerede izlenir?',
|
||
'a' => $anime->title . ', Animexe\'de Türkçe altyazılı ve Türkçe dublajlı olarak ücretsiz HD kalitede izlenebilir.',
|
||
];
|
||
$epCount = $anime->episode_count ?: $anime->episodes->count();
|
||
if ($epCount > 0) {
|
||
$__faqItems[] = [
|
||
'q' => $anime->title . ' kaç bölüm?',
|
||
'a' => $anime->type === 'movie'
|
||
? $anime->title . ' tek bölümlük bir anime filmidir.'
|
||
: $anime->title . ' şu an Animexe\'de ' . $epCount . ' bölümüyle yayında.',
|
||
];
|
||
}
|
||
if ($anime->release_year) {
|
||
$__faqItems[] = [
|
||
'q' => $anime->title . ' ne zaman çıktı?',
|
||
'a' => $anime->title . ', ' . $anime->release_year . ' yılında yayımlanmaya başladı.',
|
||
];
|
||
}
|
||
if ($anime->genres->count()) {
|
||
$__faqItems[] = [
|
||
'q' => $anime->title . ' hangi türde?',
|
||
'a' => $anime->title . ', ' . $__animeGenres . ' türlerinde bir anime' . ($anime->type === 'movie' ? ' filmidir.' : ' dizisidir.'),
|
||
];
|
||
}
|
||
if ($anime->rating) {
|
||
$__faqItems[] = [
|
||
'q' => $anime->title . ' puanı nedir?',
|
||
'a' => $anime->title . '\' un Animexe kullanıcı puanı 10 üzerinden ' . number_format($anime->rating,1) . '\'dir.',
|
||
];
|
||
}
|
||
$statusText = match($anime->status ?? '') {
|
||
'ongoing' => $anime->title . ' devam eden bir anime olup yeni bölümleri Animexe\'de yayımlanmaktadır.',
|
||
'completed' => $anime->title . ' tamamlanmış bir anime olup tüm bölümleri Animexe\'de mevcuttur.',
|
||
default => null,
|
||
};
|
||
if ($statusText) {
|
||
$__faqItems[] = ['q' => $anime->title . ' bitti mi, devam ediyor mu?', 'a' => $statusText];
|
||
}
|
||
if ($anime->studio) {
|
||
$__faqItems[] = [
|
||
'q' => $anime->title . '\'u hangi stüdyo yaptı?',
|
||
'a' => $anime->title . ', ' . $anime->studio . ' stüdyosu tarafından üretilmiştir.',
|
||
];
|
||
}
|
||
@endphp
|
||
@section('title', $__animeSeoTitle)
|
||
@section('meta_description', $__animeSeoDesc)
|
||
@section('meta_keywords', $anime->title . ' izle, ' . $anime->title . ' türkçe izle, ' . ($anime->title_en ? $anime->title_en . ' izle, ' : '') . 'anime izle, türkçe anime, ' . $__animeGenres . ' anime izle')
|
||
@section('og_type', $anime->type === 'movie' ? 'video.movie' : 'video.tv_show')
|
||
@section('og_title', $__animeSeoTitle)
|
||
@section('og_description', $__animeSeoDesc)
|
||
@section('og_image', $__animeOgImg)
|
||
@section('og_image_width', '1280')
|
||
@section('og_image_height', '720')
|
||
@section('canonical', $__animeCanon)
|
||
{{-- LCP: Cover görseli preload --}}
|
||
@section('preload')
|
||
@if($anime->bannerUrl ?? $anime->coverUrl)
|
||
<link rel="preload" as="image" href="{{ $anime->bannerUrl ?? $anime->coverUrl }}" fetchpriority="high">
|
||
@endif
|
||
@endsection
|
||
{{-- JSON-LD schemas --}}
|
||
@section('schema')
|
||
@if((\App\Models\Setting::get('seo_enable_schema','1')) === '1')
|
||
|
||
{{-- 1. TVSeries / Movie --}}
|
||
<script type="application/ld+json">
|
||
{
|
||
"@@context":"https://schema.org",
|
||
"@@type":"{{ $__animeType }}",
|
||
"name":"{{ addslashes($anime->title) }}",
|
||
@if($anime->title_en)"alternateName":"{{ addslashes($anime->title_en) }}",@endif
|
||
"url":"{{ $__animeCanon }}",
|
||
"description":"{{ addslashes(Str::limit(strip_tags($anime->description ?? ''), 300)) }}",
|
||
@if($anime->release_year)"startDate":"{{ $anime->release_year }}",@endif
|
||
@if($anime->rating)"aggregateRating":{"@@type":"AggregateRating","ratingValue":"{{ number_format($anime->rating,1) }}","bestRating":"10","worstRating":"1","ratingCount":"{{ max(1,$anime->episodes->count()) }}"},@endif
|
||
@if($anime->coverUrl)"image":{"@@type":"ImageObject","url":"{{ $anime->coverUrl }}","width":460,"height":650},@endif
|
||
@if($anime->studio)"productionCompany":{"@@type":"Organization","name":"{{ addslashes($anime->studio) }}"},@endif
|
||
@if($anime->genres->count())"genre":[{{ $anime->genres->map(fn($g)=>'"'.addslashes($g->name).'"')->implode(',') }}],@endif
|
||
"potentialAction":{"@@type":"WatchAction","target":{"@@type":"EntryPoint","urlTemplate":"{{ $__animeCanon }}","inLanguage":"tr","actionPlatform":["http://schema.org/DesktopWebPlatform","http://schema.org/MobileWebPlatform"]}},
|
||
"speakable":{"@@type":"SpeakableSpecification","xpath":["/html/head/title","/html/body//h1","/html/body//*[contains(@class,'ah-desc')]"]},
|
||
"inLanguage":"ja",
|
||
"countryOfOrigin":{"@@type":"Country","name":"Japan"},
|
||
"offers":{"@@type":"Offer","price":"0","priceCurrency":"TRY","availability":"https://schema.org/InStock","url":"{{ $__animeCanon }}"}
|
||
}
|
||
</script>
|
||
|
||
{{-- 2. VideoObject --}}
|
||
<script type="application/ld+json">
|
||
{
|
||
"@@context":"https://schema.org",
|
||
"@@type":"VideoObject",
|
||
"name":"{{ addslashes($anime->title) }} {{ $__izleLabel }} - Türkçe Altyazılı",
|
||
"description":"{{ addslashes(Str::limit(strip_tags($anime->description ?? $__animeSeoDesc), 300)) }}",
|
||
"thumbnailUrl":"{{ $anime->coverUrl ?? $anime->bannerUrl ?? url('/logo.jpg') }}",
|
||
"uploadDate":"{{ ($anime->created_at ?? now())->toIso8601String() }}",
|
||
"contentUrl":"{{ $__animeCanon }}",
|
||
"embedUrl":"{{ $__animeCanon }}",
|
||
"inLanguage":"tr",
|
||
@if($anime->rating)"aggregateRating":{"@@type":"AggregateRating","ratingValue":"{{ number_format($anime->rating,1) }}","bestRating":"10","worstRating":"1","ratingCount":"{{ max(1,$anime->episodes->count()) }}"},@endif
|
||
"publisher":{"@@type":"Organization","name":"Animexe","logo":{"@@type":"ImageObject","url":"{{ url('/logo.jpg') }}"}}
|
||
}
|
||
</script>
|
||
|
||
{{-- 3. FAQPage (auto-generated) --}}
|
||
@if(count($__faqItems) > 0)
|
||
<script type="application/ld+json">
|
||
{
|
||
"@@context":"https://schema.org",
|
||
"@@type":"FAQPage",
|
||
"mainEntity":[
|
||
@foreach($__faqItems as $i => $fq)
|
||
{"@@type":"Question","name":"{{ addslashes($fq['q']) }}","acceptedAnswer":{"@@type":"Answer","text":"{{ addslashes($fq['a']) }}"}}{{ $i < count($__faqItems)-1 ? ',' : '' }}
|
||
@endforeach
|
||
]
|
||
}
|
||
</script>
|
||
@endif
|
||
|
||
{{-- 4. Episode ItemList --}}
|
||
@php $__epList = $anime->episodes->take(20); @endphp
|
||
@if($__epList->count() > 0 && $anime->type !== 'movie')
|
||
<script type="application/ld+json">
|
||
{
|
||
"@@context":"https://schema.org",
|
||
"@@type":"ItemList",
|
||
"name":"{{ addslashes($anime->title) }} Bölüm Listesi",
|
||
"description":"{{ addslashes($anime->title) }} tüm bölümleri Animexe'de Türkçe altyazılı izle",
|
||
"numberOfItems":{{ $__epList->count() }},
|
||
"itemListElement":[
|
||
@foreach($__epList as $i => $__ep)
|
||
@php
|
||
$__epSeason = $__ep->season_id ? $anime->seasons->firstWhere('id',$__ep->season_id) : null;
|
||
$__epSNum = $__epSeason->season_number ?? 1;
|
||
@endphp
|
||
{"@@type":"ListItem","position":{{ $i+1 }},"name":"{{ addslashes($anime->title) }} {{ $__epSNum }}. Sezon {{ $__ep->episode_number }}. Bölüm İzle","url":"{{ $__domain }}{{ route('watch',[$anime->slug,$__epSNum,$__ep->episode_number],false) }}"}{{ $i < $__epList->count()-1 ? ',' : '' }}
|
||
@endforeach
|
||
]
|
||
}
|
||
</script>
|
||
@endif
|
||
|
||
{{-- 5. BreadcrumbList --}}
|
||
@if((\App\Models\Setting::get('seo_enable_breadcrumb','1')) === '1')
|
||
<script type="application/ld+json">
|
||
{
|
||
"@@context":"https://schema.org",
|
||
"@@type":"BreadcrumbList",
|
||
"itemListElement":[
|
||
{"@@type":"ListItem","position":1,"name":"Ana Sayfa","item":"{{ $__domain }}/"},
|
||
{"@@type":"ListItem","position":2,"name":"Anime","item":"{{ $__domain }}/search"},
|
||
{"@@type":"ListItem","position":3,"name":"{{ addslashes($anime->title) }} {{ $__izleLabel }}","item":"{{ $__animeCanon }}"}
|
||
]
|
||
}
|
||
</script>
|
||
@endif
|
||
|
||
@endif
|
||
@endsection
|
||
@push('styles')
|
||
<style>
|
||
/* ═══════════════════════════════════════════════════
|
||
ANIME DETAIL PAGE — REDESIGN
|
||
═══════════════════════════════════════════════════ */
|
||
|
||
/* ── Hero ──────────────────────────────────────────── */
|
||
.ah{position:relative;overflow:hidden;background:#05050e}
|
||
.ah-bg{
|
||
position:absolute;inset:0;
|
||
background-size:cover;background-position:center 25%;
|
||
transform:scale(1.05);
|
||
filter:blur(2px) saturate(1.2) brightness(.55);
|
||
transition:transform 12s ease;
|
||
}
|
||
.ah-bg.loaded{transform:scale(1)}
|
||
.ah-overlay{
|
||
position:absolute;inset:0;
|
||
background:
|
||
linear-gradient(105deg, rgba(5,5,14,.97) 0%, rgba(5,5,14,.82) 42%, rgba(5,5,14,.25) 100%),
|
||
linear-gradient(to top, #05050e 0%, rgba(5,5,14,.6) 35%, transparent 65%);
|
||
}
|
||
.ah-noise{
|
||
position:absolute;inset:0;
|
||
background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.04'/%3E%3C/svg%3E");
|
||
opacity:.6;pointer-events:none;mix-blend-mode:overlay;
|
||
}
|
||
.ah-inner{
|
||
position:relative;z-index:2;
|
||
max-width:1300px;margin:0 auto;
|
||
padding:clamp(60px,10vw,100px) clamp(20px,5vw,64px) clamp(40px,6vw,72px);
|
||
display:grid;
|
||
grid-template-columns:1fr clamp(180px,20vw,260px);
|
||
gap:clamp(24px,4vw,56px);
|
||
align-items:end;
|
||
}
|
||
/* ── Poster ─────────────────────────────────────────── */
|
||
.ah-poster{
|
||
position:relative;
|
||
border-radius:14px;overflow:hidden;
|
||
box-shadow:0 40px 80px rgba(0,0,0,.8),0 0 0 1px rgba(255,255,255,.08),0 0 60px rgba(0,245,255,.08);
|
||
transform:translateY(30px);
|
||
transition:transform .4s ease,box-shadow .4s ease;
|
||
align-self:flex-end;
|
||
}
|
||
.ah-poster:hover{transform:translateY(24px);box-shadow:0 44px 88px rgba(0,0,0,.85),0 0 0 1px rgba(0,245,255,.2),0 0 80px rgba(255,45,125,.12)}
|
||
.ah-poster img{width:100%;display:block;aspect-ratio:2/3;object-fit:cover}
|
||
.ah-poster-ph{aspect-ratio:2/3;display:flex;align-items:center;justify-content:center;color:rgba(255,255,255,.2);font-size:3rem;background:rgba(255,255,255,.04)}
|
||
.ah-poster-score{
|
||
position:absolute;bottom:0;left:0;right:0;
|
||
padding:20px 12px 10px;
|
||
background:linear-gradient(to top,rgba(0,0,0,.9),transparent);
|
||
text-align:center;
|
||
font-size:.95rem;font-weight:800;color:#fbbf24;
|
||
letter-spacing:.03em;
|
||
}
|
||
.ah-poster-score i{font-size:.75rem;margin-right:3px}
|
||
|
||
/* ── Meta ──────────────────────────────────────────── */
|
||
.ah-meta{display:flex;flex-direction:column;gap:0;padding-bottom:4px}
|
||
.ah-badges{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:14px}
|
||
.badge{padding:4px 12px;border-radius:20px;font-size:.7rem;font-weight:700;border:1px solid transparent;letter-spacing:.04em;text-transform:uppercase}
|
||
.b-type{background:rgba(147,51,234,.18);border-color:rgba(147,51,234,.45);color:#c084fc}
|
||
.b-on{background:rgba(34,197,94,.12);border-color:rgba(34,197,94,.35);color:#4ade80}
|
||
.b-done{background:rgba(59,130,246,.12);border-color:rgba(59,130,246,.35);color:#60a5fa}
|
||
.b-up{background:rgba(245,158,11,.12);border-color:rgba(245,158,11,.35);color:#fbbf24}
|
||
.b-yr{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.12);color:rgba(255,255,255,.5)}
|
||
.ah-title{
|
||
font-family:var(--font-display);
|
||
font-size:clamp(1.9rem,5vw,4rem);
|
||
font-weight:900;line-height:1.04;letter-spacing:-.02em;margin-bottom:10px;
|
||
background:linear-gradient(130deg,#fff 0%,rgba(255,255,255,.92) 55%,rgba(200,220,255,.75) 100%);
|
||
-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;
|
||
filter:drop-shadow(0 4px 32px rgba(255,255,255,.1));
|
||
}
|
||
.ah-sub{
|
||
color:rgba(255,255,255,.42);font-size:.88rem;margin-bottom:16px;font-weight:400;
|
||
display:flex;align-items:center;gap:8px;flex-wrap:wrap;
|
||
}
|
||
.ah-sub-sep{width:3px;height:3px;border-radius:50%;background:rgba(255,255,255,.25);flex-shrink:0}
|
||
.ah-inline-score{
|
||
display:inline-flex;align-items:center;gap:5px;
|
||
background:rgba(251,191,36,.12);border:1px solid rgba(251,191,36,.28);
|
||
padding:3px 11px;border-radius:20px;
|
||
color:#fbbf24;font-weight:800;font-size:.82rem;
|
||
}
|
||
.ah-genres{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:20px}
|
||
.ah-genre-chip{
|
||
padding:5px 13px;border-radius:20px;
|
||
background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.1);
|
||
color:rgba(255,255,255,.55);font-size:.74rem;font-weight:500;
|
||
transition:all .15s;text-decoration:none;
|
||
}
|
||
.ah-genre-chip:hover{background:rgba(0,245,255,.1);border-color:rgba(0,245,255,.3);color:var(--accent2)}
|
||
|
||
/* ── Action buttons ────────────────────────────────── */
|
||
.ah-actions{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:16px;align-items:center}
|
||
.ah-play{
|
||
display:inline-flex;align-items:center;gap:10px;
|
||
padding:16px 34px;border-radius:14px;
|
||
background:linear-gradient(135deg,var(--accent) 0%,var(--accent3) 100%);
|
||
color:#fff;font-size:.96rem;font-weight:900;border:none;cursor:pointer;text-decoration:none;
|
||
transition:transform .15s,box-shadow .2s,filter .15s;
|
||
box-shadow:0 0 44px rgba(255,45,125,.48),0 8px 24px rgba(0,0,0,.45);
|
||
letter-spacing:.03em;
|
||
position:relative;overflow:hidden;
|
||
}
|
||
.ah-play::before{
|
||
content:'';position:absolute;inset:0;
|
||
background:linear-gradient(135deg,transparent 40%,rgba(255,255,255,.12) 50%,transparent 60%);
|
||
transform:translateX(-100%) skewX(-15deg);transition:transform .5s ease;
|
||
}
|
||
.ah-play:hover::before{transform:translateX(200%) skewX(-15deg)}
|
||
.ah-play:hover{transform:translateY(-3px);filter:brightness(1.08);box-shadow:0 0 60px rgba(255,45,125,.62),0 10px 32px rgba(0,0,0,.5)}
|
||
.ah-play i{font-size:1.15rem}
|
||
.ah-btn{
|
||
display:inline-flex;align-items:center;gap:7px;
|
||
padding:13px 20px;border-radius:14px;
|
||
background:rgba(255,255,255,.07);backdrop-filter:blur(12px);
|
||
border:1px solid rgba(255,255,255,.13);
|
||
color:rgba(255,255,255,.8);font-size:.84rem;font-weight:600;
|
||
transition:all .18s;text-decoration:none;cursor:pointer;font-family:inherit;
|
||
white-space:nowrap;
|
||
}
|
||
.ah-btn:hover{background:rgba(0,245,255,.1);border-color:rgba(0,245,255,.3);color:var(--accent2)}
|
||
.ah-btn.active-wl{border-color:rgba(255,45,125,.4);color:var(--accent)}
|
||
.ah-btn.active-fl{border-color:rgba(0,245,255,.4);color:var(--accent2)}
|
||
|
||
/* ── User rating row ────────────────────────────────── */
|
||
.ah-rating{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
||
.ah-rating-lbl{font-size:.76rem;color:rgba(255,255,255,.4);font-weight:500;white-space:nowrap}
|
||
.star-btn{
|
||
width:28px;height:28px;border-radius:8px;
|
||
border:1px solid rgba(255,255,255,.1);background:rgba(255,255,255,.05);
|
||
color:rgba(255,255,255,.35);font-size:.72rem;cursor:pointer;
|
||
transition:all .12s;padding:0;font-family:inherit;
|
||
}
|
||
.star-btn:hover,.star-btn.on{
|
||
background:linear-gradient(135deg,var(--accent),var(--accent3));
|
||
border-color:transparent;color:#fff;
|
||
box-shadow:0 0 12px rgba(255,45,125,.4);
|
||
}
|
||
|
||
/* ── Stats strip ────────────────────────────────────── */
|
||
.a-body{max-width:1300px;margin:0 auto;padding:0 clamp(14px,4vw,28px) 60px}
|
||
.a-stats-strip{
|
||
display:flex;gap:10px;
|
||
margin-top:clamp(40px,6vw,60px);
|
||
margin-bottom:32px;
|
||
overflow-x:auto;
|
||
scrollbar-width:none;
|
||
-webkit-overflow-scrolling:touch;
|
||
padding-bottom:4px;
|
||
}
|
||
.a-stats-strip::-webkit-scrollbar{display:none}
|
||
.a-stat-card{
|
||
display:flex;align-items:center;gap:12px;
|
||
background:rgba(255,255,255,.04);
|
||
border:1px solid rgba(255,255,255,.07);
|
||
border-radius:12px;padding:14px 20px;
|
||
flex-shrink:0;
|
||
transition:border-color .18s,background .18s;
|
||
}
|
||
.a-stat-card:hover{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.12)}
|
||
.a-stat-icon{
|
||
width:36px;height:36px;border-radius:10px;flex-shrink:0;
|
||
display:flex;align-items:center;justify-content:center;font-size:.9rem;
|
||
}
|
||
.a-stat-icon.gold{background:rgba(251,191,36,.12);color:#fbbf24}
|
||
.a-stat-icon.cyan{background:rgba(0,245,255,.1);color:var(--accent2)}
|
||
.a-stat-icon.pink{background:rgba(255,45,125,.1);color:var(--accent)}
|
||
.a-stat-icon.purple{background:rgba(147,51,234,.12);color:#c084fc}
|
||
.a-stat-icon.muted{background:rgba(255,255,255,.06);color:rgba(255,255,255,.4)}
|
||
.a-stat-info{min-width:0;flex:1}
|
||
.a-stat-val{font-size:.9rem;font-weight:800;color:var(--text);line-height:1.2}
|
||
.a-stat-lbl{font-size:.62rem;text-transform:uppercase;letter-spacing:.08em;color:var(--text3);font-weight:600;margin-top:2px}
|
||
|
||
/* ── Description ────────────────────────────────────── */
|
||
.a-desc-wrap{
|
||
margin-bottom:32px;
|
||
padding:24px;
|
||
background:rgba(255,255,255,.025);
|
||
border:1px solid rgba(255,255,255,.06);
|
||
border-radius:16px;
|
||
}
|
||
.a-desc{color:rgba(255,255,255,.65);font-size:.92rem;line-height:1.8}
|
||
.a-desc.clamped{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
|
||
.a-desc-btn{
|
||
background:none;border:none;color:var(--accent2);font-size:.8rem;cursor:pointer;
|
||
margin-top:10px;padding:0;font-family:inherit;display:inline-flex;align-items:center;gap:5px;
|
||
opacity:.75;transition:opacity .15s;
|
||
}
|
||
.a-desc-btn:hover{opacity:1}
|
||
|
||
/* ── Tabs ───────────────────────────────────────────── */
|
||
.a-tabs{
|
||
display:flex;gap:4px;margin-bottom:24px;
|
||
background:rgba(255,255,255,.03);
|
||
border:1px solid rgba(255,255,255,.07);
|
||
border-radius:14px;padding:5px;
|
||
overflow-x:auto;scrollbar-width:none;
|
||
}
|
||
.a-tabs::-webkit-scrollbar{display:none}
|
||
.a-tab{
|
||
padding:11px 22px;background:none;border:none;border-radius:10px;
|
||
color:rgba(255,255,255,.42);font-size:.88rem;font-weight:700;
|
||
cursor:pointer;font-family:inherit;transition:all .15s;
|
||
white-space:nowrap;flex-shrink:0;display:flex;align-items:center;gap:7px;
|
||
}
|
||
.a-tab:hover{color:rgba(255,255,255,.72);background:rgba(255,255,255,.06)}
|
||
.a-tab.on{
|
||
background:rgba(0,245,255,.12);color:var(--accent2);
|
||
box-shadow:inset 0 0 0 1px rgba(0,245,255,.25),0 0 20px rgba(0,245,255,.06);
|
||
}
|
||
.a-tab.on i{filter:drop-shadow(0 0 8px rgba(0,245,255,.6))}
|
||
.tab-pane{display:none}
|
||
.tab-pane.on{display:block}
|
||
|
||
/* ── Season selector ────────────────────────────────── */
|
||
.season-tabs{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:20px}
|
||
.s-btn{
|
||
padding:7px 18px;border-radius:10px;
|
||
background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.08);
|
||
color:rgba(255,255,255,.5);font-size:.8rem;font-weight:600;
|
||
cursor:pointer;font-family:inherit;transition:all .15s;
|
||
}
|
||
.s-btn:hover{border-color:rgba(0,245,255,.25);color:var(--accent2)}
|
||
.s-btn.on{
|
||
background:rgba(0,245,255,.1);border-color:rgba(0,245,255,.3);color:var(--accent2);
|
||
}
|
||
|
||
/* ── Episode list ───────────────────────────────────── */
|
||
.ep-list{display:flex;flex-direction:column;gap:8px}
|
||
.ep-card{
|
||
display:flex;gap:14px;
|
||
background:rgba(255,255,255,.03);
|
||
border:1px solid rgba(255,255,255,.07);
|
||
border-radius:14px;padding:12px;
|
||
cursor:pointer;text-decoration:none;color:inherit;
|
||
transition:all .18s;
|
||
}
|
||
.ep-card:hover{
|
||
background:rgba(0,245,255,.05);
|
||
border-color:rgba(0,245,255,.2);
|
||
transform:translateX(3px);
|
||
}
|
||
@media(hover:none){
|
||
.ep-card:hover{transform:none}
|
||
.ep-card:active{background:rgba(0,245,255,.07);border-color:rgba(0,245,255,.2)}
|
||
}
|
||
.ep-card-thumb{
|
||
flex-shrink:0;width:130px;border-radius:9px;overflow:hidden;
|
||
background:rgba(255,255,255,.06);position:relative;aspect-ratio:16/9;
|
||
align-self:flex-start;
|
||
}
|
||
@media(max-width:500px){.ep-card-thumb{width:100px}}
|
||
.ep-card-thumb img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .3s}
|
||
.ep-card:hover .ep-card-thumb img{transform:scale(1.06)}
|
||
.ep-card-thumb .no-thumb{width:100%;height:100%;display:flex;align-items:center;justify-content:center;color:rgba(255,255,255,.2);font-size:1.5rem}
|
||
.ep-play-overlay{
|
||
position:absolute;inset:0;background:rgba(0,0,0,.45);
|
||
display:flex;align-items:center;justify-content:center;
|
||
opacity:0;transition:opacity .18s;
|
||
}
|
||
.ep-card:hover .ep-play-overlay{opacity:1}
|
||
.ep-play-overlay i{font-size:1.4rem;color:#fff;filter:drop-shadow(0 0 10px rgba(0,245,255,.7))}
|
||
.ep-num-badge{
|
||
position:absolute;top:6px;left:6px;
|
||
background:rgba(0,0,0,.75);backdrop-filter:blur(4px);
|
||
color:rgba(255,255,255,.8);font-size:.6rem;font-weight:700;
|
||
padding:2px 7px;border-radius:5px;letter-spacing:.04em;
|
||
}
|
||
.ep-card-body{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center;gap:4px;padding:2px 0}
|
||
.ep-card-num{font-size:.67rem;color:var(--accent2);font-weight:700;letter-spacing:.08em;text-transform:uppercase}
|
||
.ep-card-title{font-size:.88rem;font-weight:700;color:var(--text);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;line-height:1.45}
|
||
.ep-card-meta{font-size:.72rem;color:rgba(255,255,255,.3);display:flex;align-items:center;gap:10px;flex-wrap:wrap}
|
||
|
||
/* ── Info table ─────────────────────────────────────── */
|
||
.info-table{width:100%;border-collapse:collapse}
|
||
.info-table tr{border-bottom:1px solid rgba(255,255,255,.05)}
|
||
.info-table tr:last-child{border-bottom:none}
|
||
.info-table td{padding:13px 0;font-size:.88rem;vertical-align:top}
|
||
.info-table td:first-child{color:rgba(255,255,255,.35);width:140px;font-weight:600;font-size:.78rem;text-transform:uppercase;letter-spacing:.08em;padding-top:16px}
|
||
|
||
/* ── Related / AI grid ──────────────────────────────── */
|
||
.rel-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:12px}
|
||
.ah-genre-chip{padding:5px 13px;border-radius:20px;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.1);color:rgba(255,255,255,.55);font-size:.74rem;font-weight:500;transition:all .15s;text-decoration:none}
|
||
|
||
/* ── Watchlist dropdown ─────────────────────────────── */
|
||
.wl-opt{display:flex;align-items:center;gap:8px;width:100%;padding:8px 11px;border-radius:8px;border:none;background:transparent;color:rgba(255,255,255,.6);font-size:.82rem;cursor:pointer;transition:background .15s}
|
||
.wl-opt:hover,.wl-opt-on{background:rgba(255,255,255,.07);color:#fff}
|
||
.wl-opt-on{color:var(--accent)}
|
||
|
||
/* ── Login prompt modal ─────────────────────────────── */
|
||
.login-prompt-overlay{position:fixed;inset:0;background:rgba(0,0,0,.75);z-index:9999;display:flex;align-items:center;justify-content:center;backdrop-filter:blur(8px)}
|
||
.login-prompt-box{background:#0e0e1a;border:1px solid rgba(255,255,255,.1);border-radius:20px;padding:36px 30px;text-align:center;max-width:340px;width:90%;box-shadow:0 32px 80px rgba(0,0,0,.6)}
|
||
.login-prompt-box h3{color:#fff;font-size:1.1rem;margin-bottom:8px}
|
||
.login-prompt-box p{color:rgba(255,255,255,.45);font-size:.85rem;margin-bottom:20px}
|
||
.lp-btn{display:inline-block;padding:10px 26px;border-radius:12px;font-size:.88rem;font-weight:700;text-decoration:none}
|
||
.lp-btn-primary{background:linear-gradient(135deg,var(--accent),var(--accent3));color:#fff;margin-right:8px}
|
||
.lp-btn-secondary{background:rgba(255,255,255,.08);color:rgba(255,255,255,.6);border:1px solid rgba(255,255,255,.1)}
|
||
|
||
/* ── Achievement popup ──────────────────────────────── */
|
||
.ach-popup{position:fixed;bottom:24px;right:24px;background:#0e0e1a;border:1px solid rgba(255,255,255,.1);border-radius:14px;padding:14px 18px;display:flex;align-items:center;gap:12px;z-index:9998;animation:slideUp .3s ease;box-shadow:0 12px 40px rgba(0,0,0,.6)}
|
||
@keyframes slideUp{from{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}
|
||
.ach-popup .ach-icon{font-size:1.8rem}
|
||
.ach-popup .ach-title{font-size:.75rem;color:rgba(255,255,255,.4)}
|
||
.ach-popup .ach-name{font-size:.9rem;font-weight:700;color:#fff}
|
||
|
||
/* ══ RESPONSIVE ═══════════════════════════════════════ */
|
||
@media(max-width:900px){
|
||
.ah-inner{grid-template-columns:1fr clamp(140px,18vw,200px);gap:20px}
|
||
}
|
||
/* Tablet/large phone — remove poster, stack cleanly */
|
||
@media(max-width:700px){
|
||
.ah-inner{
|
||
grid-template-columns:1fr;
|
||
padding:clamp(24px,8vw,48px) 16px 28px;
|
||
}
|
||
.ah-poster{display:none}
|
||
.ah-title{font-size:clamp(1.3rem,5.5vw,1.9rem)}
|
||
.ah-play{padding:12px 22px;font-size:.86rem}
|
||
.ah-btn{padding:11px 16px;font-size:.8rem}
|
||
.a-stats-strip{gap:8px}
|
||
.a-stat-card{padding:11px 15px;gap:9px}
|
||
.a-stat-icon{width:30px;height:30px;font-size:.78rem}
|
||
.a-stat-val{font-size:.88rem}
|
||
}
|
||
/* Phone — stacked hero with top banner visual */
|
||
@media(max-width:480px){
|
||
.ah{padding-top:0}
|
||
.ah-bg{filter:blur(3px) saturate(1.1) brightness(.45)}
|
||
.ah-overlay{background:linear-gradient(to bottom,rgba(5,5,14,.4) 0%,rgba(5,5,14,.8) 50%,#05050e 85%)}
|
||
/* 180px was too high — banner is visible but content was pushed off-screen */
|
||
.ah-inner{padding:clamp(80px,20vw,130px) 14px 24px}
|
||
.ah-badges{margin-bottom:10px}
|
||
.ah-sub{margin-bottom:12px}
|
||
.ah-genres{margin-bottom:14px}
|
||
.ah-actions{gap:8px}
|
||
.ah-play{width:100%;justify-content:center}
|
||
.ah-btn{flex:1;justify-content:center}
|
||
.a-stats-strip{margin-top:24px}
|
||
.ep-card-thumb{width:90px}
|
||
.a-tabs{border-radius:12px}
|
||
.a-tab{padding:8px 13px;font-size:.78rem}
|
||
/* Larger star touch targets on mobile (was 28px, iOS HIG min 44pt) */
|
||
.star-btn{width:36px;height:36px;font-size:.8rem;border-radius:10px}
|
||
.ah-rating{gap:6px}
|
||
}
|
||
@media(max-width:400px){
|
||
/* Info table: narrow label column on very small phones */
|
||
.info-table td:first-child{width:100px;font-size:.74rem}
|
||
/* Achievement popup: stretch edge-to-edge instead of overflowing */
|
||
.ach-popup{left:10px;right:10px;bottom:14px;max-width:none}
|
||
}
|
||
|
||
/* ═══════════════════════════════════════════════════
|
||
ANIME PAGE PREMIUM ENHANCEMENTS
|
||
═══════════════════════════════════════════════════ */
|
||
|
||
/* Hero entrance animations */
|
||
@keyframes ah-fade-up{
|
||
from{opacity:0;transform:translateY(22px)}
|
||
to{opacity:1;transform:none}
|
||
}
|
||
.ah-badges{animation:ah-fade-up .5s cubic-bezier(.22,1,.36,1) .15s both}
|
||
.ah-title{animation:ah-fade-up .6s cubic-bezier(.22,1,.36,1) .25s both}
|
||
.ah-sub{animation:ah-fade-up .5s cubic-bezier(.22,1,.36,1) .35s both}
|
||
.ah-genres{animation:ah-fade-up .5s cubic-bezier(.22,1,.36,1) .4s both}
|
||
.ah-actions{animation:ah-fade-up .5s cubic-bezier(.22,1,.36,1) .5s both}
|
||
.ah-poster{animation:ah-fade-up .7s cubic-bezier(.22,1,.36,1) .3s both}
|
||
|
||
/* Title gradient glow */
|
||
.ah-title{
|
||
background:linear-gradient(135deg,#fff 0%,rgba(255,255,255,.88) 60%,rgba(240,244,255,.65) 100%);
|
||
-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;
|
||
}
|
||
|
||
/* Poster reflection effect */
|
||
.ah-poster::after{
|
||
content:'';position:absolute;bottom:0;left:0;right:0;height:60%;
|
||
background:linear-gradient(to top,rgba(5,5,14,.85),transparent);
|
||
pointer-events:none;
|
||
}
|
||
.ah-poster::before{
|
||
content:'';position:absolute;inset:0;
|
||
background:linear-gradient(115deg,transparent 35%,rgba(255,255,255,.06) 50%,transparent 65%);
|
||
z-index:3;transform:translateX(-100%);
|
||
transition:transform .7s ease;
|
||
}
|
||
.ah-poster:hover::before{transform:translateX(200%)}
|
||
|
||
/* Stats strip counter anim */
|
||
@keyframes stat-pop{
|
||
from{opacity:0;transform:scale(.9) translateY(8px)}
|
||
to{opacity:1;transform:none}
|
||
}
|
||
.a-stat-card{animation:stat-pop .45s cubic-bezier(.22,1,.36,1) both}
|
||
.a-stat-card:nth-child(1){animation-delay:.1s}
|
||
.a-stat-card:nth-child(2){animation-delay:.16s}
|
||
.a-stat-card:nth-child(3){animation-delay:.22s}
|
||
.a-stat-card:nth-child(4){animation-delay:.28s}
|
||
.a-stat-card:nth-child(5){animation-delay:.34s}
|
||
.a-stat-card:nth-child(6){animation-delay:.4s}
|
||
|
||
/* Stats strip icon glow on hover */
|
||
.a-stat-card:hover .a-stat-icon.gold{box-shadow:0 0 20px rgba(251,191,36,.25)}
|
||
.a-stat-card:hover .a-stat-icon.cyan{box-shadow:0 0 20px rgba(0,245,255,.2)}
|
||
.a-stat-card:hover .a-stat-icon.pink{box-shadow:0 0 20px rgba(255,45,125,.2)}
|
||
.a-stat-card:hover .a-stat-icon.purple{box-shadow:0 0 20px rgba(184,77,255,.2)}
|
||
|
||
/* Episode card enhanced */
|
||
.ep-card{
|
||
border:1px solid rgba(255,255,255,.06);
|
||
position:relative;overflow:hidden;
|
||
}
|
||
.ep-card::before{
|
||
content:'';position:absolute;left:0;top:0;bottom:0;width:2px;
|
||
background:linear-gradient(180deg,var(--accent2),var(--accent));
|
||
transform:scaleY(0);transform-origin:bottom;
|
||
transition:transform .25s cubic-bezier(.22,1,.36,1);
|
||
}
|
||
.ep-card:hover::before{transform:scaleY(1)}
|
||
|
||
/* Tab active glow */
|
||
.a-tab.on{
|
||
box-shadow:inset 0 0 0 1px rgba(0,245,255,.25),0 0 24px rgba(0,245,255,.06);
|
||
}
|
||
|
||
/* Inline score glow */
|
||
.ah-inline-score:hover{
|
||
background:rgba(251,191,36,.2);
|
||
box-shadow:0 0 16px rgba(251,191,36,.2);
|
||
}
|
||
|
||
/* Play button pulse */
|
||
.ah-play::after{
|
||
content:'';position:absolute;inset:0;border-radius:14px;
|
||
box-shadow:0 0 0 0 rgba(255,45,125,.4);
|
||
animation:play-ripple 2s ease-out infinite;
|
||
}
|
||
@keyframes play-ripple{
|
||
0%{box-shadow:0 0 0 0 rgba(255,45,125,.35)}
|
||
70%{box-shadow:0 0 0 12px rgba(255,45,125,0)}
|
||
100%{box-shadow:0 0 0 0 rgba(255,45,125,0)}
|
||
}
|
||
.ah-play{position:relative;overflow:hidden}
|
||
|
||
/* Description box */
|
||
.a-desc-wrap{
|
||
background:linear-gradient(135deg,rgba(255,255,255,.03),rgba(0,245,255,.015));
|
||
border:1px solid rgba(0,245,255,.07);
|
||
}
|
||
|
||
/* Genre chips hover effect */
|
||
.ah-genre-chip{
|
||
position:relative;overflow:hidden;
|
||
}
|
||
.ah-genre-chip::after{
|
||
content:'';position:absolute;inset:0;background:rgba(0,245,255,.05);
|
||
transform:scaleX(0);transform-origin:left;
|
||
transition:transform .2s ease;
|
||
}
|
||
.ah-genre-chip:hover::after{transform:scaleX(1)}
|
||
|
||
/* Hero glow pulse under poster */
|
||
@keyframes poster-glow{
|
||
0%,100%{box-shadow:0 40px 80px rgba(0,0,0,.8),0 0 60px rgba(255,45,125,.06)}
|
||
50%{box-shadow:0 40px 80px rgba(0,0,0,.8),0 0 80px rgba(0,245,255,.1)}
|
||
}
|
||
.ah-poster{animation:poster-glow 4s ease-in-out infinite, ah-fade-up .7s cubic-bezier(.22,1,.36,1) .3s both}
|
||
|
||
/* Body section reveal */
|
||
.a-stats-strip,.a-desc-wrap,.a-tabs{
|
||
animation:ah-fade-up .5s cubic-bezier(.22,1,.36,1) .2s both;
|
||
}
|
||
</style>
|
||
@endpush
|
||
@section('content')
|
||
|
||
{{-- Hero --}}
|
||
<div class="ah">
|
||
@if($anime->bannerUrl ?: $anime->coverUrl)
|
||
<div class="ah-bg" id="ah-bg" style="background-image:url('{{ $anime->bannerUrl ?: $anime->coverUrl }}')"></div>
|
||
@else
|
||
<div style="position:absolute;inset:0;background:linear-gradient(135deg,rgba(20,20,40,1),rgba(5,5,14,1))"></div>
|
||
@endif
|
||
<div class="ah-overlay"></div>
|
||
<div class="ah-noise"></div>
|
||
|
||
<div class="ah-inner">
|
||
{{-- Left: info --}}
|
||
<div class="ah-meta">
|
||
<div class="ah-badges">
|
||
<span class="badge b-type">{{ $anime->type==='movie' ? 'Film' : 'Dizi' }}</span>
|
||
@if($anime->status==='ongoing')<span class="badge b-on">Devam Ediyor</span>
|
||
@elseif($anime->status==='completed')<span class="badge b-done">Tamamlandı</span>
|
||
@else<span class="badge b-up">Yakında</span>@endif
|
||
@if($anime->release_year)<span class="badge b-yr">{{ $anime->release_year }}</span>@endif
|
||
</div>
|
||
|
||
<h1 class="ah-title">{{ $anime->title }} <span style="font-size:.6em;font-weight:500;opacity:.55;letter-spacing:.02em">{{ $__izleLabel }}</span></h1>
|
||
|
||
@if($anime->title_en || $anime->rating)
|
||
<div class="ah-sub">
|
||
@if($anime->title_en)<span>{{ $anime->title_en }}</span>@endif
|
||
@if($anime->title_en && $anime->title_jp)<span class="ah-sub-sep"></span><span>{{ $anime->title_jp }}</span>@endif
|
||
@if($anime->rating)
|
||
@if($anime->title_en)<span class="ah-sub-sep"></span>@endif
|
||
<span class="ah-inline-score"><i class="bi bi-star-fill" style="font-size:.7rem"></i> {{ number_format($anime->rating,1) }}</span>
|
||
@endif
|
||
</div>
|
||
@endif
|
||
|
||
@if($anime->genres->count())
|
||
<div class="ah-genres">
|
||
@foreach($anime->genres->take(5) as $g)
|
||
<a href="{{ route('genre',$g->slug) }}" class="ah-genre-chip">{{ $g->name }}</a>
|
||
@endforeach
|
||
</div>
|
||
@endif
|
||
|
||
{{-- Action buttons --}}
|
||
<div class="ah-actions">
|
||
@if($anime->seasons->count() && $anime->seasons->first()->episodes->count())
|
||
@php $s1=$anime->seasons->first(); $e1=$s1->episodes->first(); @endphp
|
||
@auth
|
||
@if($continueEp && $continueEp->percent_complete > 3)
|
||
<a href="{{ route('watch',[$anime->slug,$continueEp->season_number,$continueEp->episode_number]) }}" class="ah-play" style="background:linear-gradient(135deg,#7c3aed,#a855f7)">
|
||
<i class="bi bi-play-circle-fill"></i>
|
||
Devam Et — S{{ str_pad($continueEp->season_number,2,'0',STR_PAD_LEFT) }}E{{ str_pad($continueEp->episode_number,2,'0',STR_PAD_LEFT) }}
|
||
<span style="font-size:.68rem;opacity:.75;margin-left:2px">%{{ $continueEp->percent_complete }}</span>
|
||
</a>
|
||
@else
|
||
<a href="{{ route('watch',[$anime->slug,$s1->season_number,$e1->episode_number]) }}" class="ah-play">
|
||
<i class="bi bi-play-fill"></i> İzlemeye Başla
|
||
</a>
|
||
@endif
|
||
@else
|
||
<a href="{{ route('watch',[$anime->slug,$s1->season_number,$e1->episode_number]) }}" class="ah-play">
|
||
<i class="bi bi-play-fill"></i> İzlemeye Başla
|
||
</a>
|
||
@endauth
|
||
@endif
|
||
|
||
{{-- Watchlist --}}
|
||
@auth
|
||
<div id="wl-wrap" style="position:relative;display:inline-flex">
|
||
<button class="ah-btn {{ $userWatchlist ? 'active-wl' : '' }}" id="wl-btn" onclick="toggleWlMenu()">
|
||
<i class="bi bi-{{ $userWatchlist ? 'bookmark-fill' : 'bookmark-plus' }}"></i>
|
||
<span class="btn-lbl">{{ $userWatchlist ? \App\Models\Watchlist::STATUSES[$userWatchlist->status] : 'Listeye Ekle' }}</span>
|
||
</button>
|
||
<div id="wl-menu" style="display:none;position:fixed;background:#0e0e1a;border:1px solid rgba(255,255,255,.12);border-radius:12px;padding:6px;z-index:9000;min-width:170px;box-shadow:0 12px 40px rgba(0,0,0,.8)">
|
||
@foreach(\App\Models\Watchlist::STATUSES as $st=>$lbl)
|
||
<button onclick="setWatchlist('{{ $st }}')" class="wl-opt {{ ($userWatchlist && $userWatchlist->status===$st) ? 'wl-opt-on' : '' }}">
|
||
<i class="bi bi-{{ $st==='plan'?'clock':($st==='watching'?'play-circle':($st==='completed'?'check-circle':'x-circle')) }}"></i> {{ $lbl }}
|
||
</button>
|
||
@endforeach
|
||
@if($userWatchlist)
|
||
<hr style="border-color:rgba(255,255,255,.07);margin:5px 0">
|
||
<button onclick="setWatchlist('{{ $userWatchlist->status }}')" class="wl-opt" style="color:#f87171">
|
||
<i class="bi bi-trash"></i> Listeden Çıkar
|
||
</button>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
@else
|
||
<a href="{{ route('frontend.login') }}" class="ah-btn">
|
||
<i class="bi bi-bookmark-plus"></i> <span class="btn-lbl">Listeye Ekle</span>
|
||
</a>
|
||
@endauth
|
||
|
||
{{-- Follow --}}
|
||
@auth
|
||
<button class="ah-btn {{ ($userFollowing ?? false) ? 'active-fl' : '' }}" id="follow-btn" onclick="toggleFollow()">
|
||
<i class="bi bi-{{ ($userFollowing ?? false) ? 'bell-fill' : 'bell' }}" id="follow-icon"></i>
|
||
<span id="follow-label" class="btn-lbl">{{ ($userFollowing ?? false) ? 'Takiptesin' : 'Takip Et' }}</span>
|
||
</button>
|
||
@else
|
||
<a href="{{ route('frontend.login') }}" class="ah-btn">
|
||
<i class="bi bi-bell"></i> <span class="btn-lbl">Takip Et</span>
|
||
</a>
|
||
@endauth
|
||
|
||
{{-- Anime Mahkemesi --}}
|
||
<a href="{{ route('tribunal.index') }}?anime={{ $anime->id }}" class="ah-btn" title="Bu anime için dava aç">
|
||
<i class="bi bi-balance"></i> <span class="btn-lbl">Mahkeme</span>
|
||
</a>
|
||
|
||
{{-- Zaman Kapsülü --}}
|
||
@auth
|
||
<button class="ah-btn" id="capsule-btn" onclick="openCapsuleModal()" title="Zaman kapsülü bırak">
|
||
<i class="bi bi-hourglass-split"></i> <span class="btn-lbl">Kapsül</span>
|
||
</button>
|
||
@endauth
|
||
|
||
{{-- Paylaş --}}
|
||
<button class="ah-btn" onclick="shareAnime()" title="Paylaş">
|
||
<i class="bi bi-share"></i> <span class="btn-lbl">Paylaş</span>
|
||
</button>
|
||
</div>
|
||
|
||
{{-- Sosyal: Kimler izliyor --}}
|
||
@if($watcherCount > 0)
|
||
<div style="display:flex;align-items:center;gap:10px;margin-top:6px;margin-bottom:4px">
|
||
<div style="display:flex">
|
||
@foreach($watchers->take(6) as $w)
|
||
<div data-uid="{{ $w->id }}" style="width:26px;height:26px;border-radius:50%;overflow:hidden;margin-right:-7px;border:2px solid #05050e;cursor:pointer;background:linear-gradient(135deg,var(--accent2),var(--accent));display:flex;align-items:center;justify-content:center;font-size:.62rem;font-weight:800;color:#fff;flex-shrink:0">
|
||
@if($w->avatar)<img src="{{ \App\Support\MediaUrl::fromStoragePath($w->avatar) }}" style="width:100%;height:100%;object-fit:cover" alt="">@else{{ mb_strtoupper(mb_substr($w->name,0,1)) }}@endif
|
||
</div>
|
||
@endforeach
|
||
</div>
|
||
<span style="font-size:.75rem;color:rgba(255,255,255,.4)">
|
||
@if($watcherCount === 1) 1 kişi listesine ekledi
|
||
@else <strong style="color:rgba(255,255,255,.65)">{{ number_format($watcherCount) }}</strong> kişi listesine ekledi
|
||
@endif
|
||
</span>
|
||
</div>
|
||
@endif
|
||
|
||
{{-- User rating --}}
|
||
@auth
|
||
<div class="ah-rating" id="rating-wrap">
|
||
<span class="ah-rating-lbl">Puanın:</span>
|
||
@for($i=1;$i<=10;$i++)
|
||
<button class="star-btn {{ $userRating >= $i ? 'on' : '' }}" data-r="{{ $i }}" onclick="rateAnime({{ $i }})">{{ $i }}</button>
|
||
@endfor
|
||
@if($userRating)<span id="my-rating-lbl" style="font-size:.76rem;color:var(--accent);margin-left:4px">{{ $userRating }}/10</span>@endif
|
||
</div>
|
||
@else
|
||
<div style="margin-top:2px">
|
||
<a href="{{ route('frontend.login') }}" style="font-size:.76rem;color:rgba(255,255,255,.28);text-decoration:none"><i class="bi bi-star me-1"></i>Giriş yap ve puan ver</a>
|
||
</div>
|
||
@endauth
|
||
</div>
|
||
|
||
{{-- Right: Poster --}}
|
||
<div class="ah-poster">
|
||
@if($anime->coverUrl)
|
||
<img src="{{ $anime->coverUrl }}" alt="{{ $anime->title }}">
|
||
@else
|
||
<div class="ah-poster-ph"><i class="bi bi-image"></i></div>
|
||
@endif
|
||
@if($anime->rating)
|
||
<div class="ah-poster-score"><i class="bi bi-star-fill"></i> {{ number_format($anime->rating,1) }}</div>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{{-- Body --}}
|
||
<div class="a-body">
|
||
|
||
{{-- Stats strip --}}
|
||
@php $totalEps = $anime->seasons->sum(fn($s) => $s->episodes->count()); @endphp
|
||
<div class="a-stats-strip">
|
||
@if($anime->rating)
|
||
<div class="a-stat-card">
|
||
<div class="a-stat-icon gold"><i class="bi bi-star-fill"></i></div>
|
||
<div class="a-stat-info">
|
||
<div class="a-stat-val">{{ number_format($anime->rating,1) }}</div>
|
||
<div class="a-stat-lbl">Puan</div>
|
||
</div>
|
||
</div>
|
||
@endif
|
||
<div class="a-stat-card">
|
||
<div class="a-stat-icon cyan"><i class="bi bi-collection-play"></i></div>
|
||
<div class="a-stat-info">
|
||
<div class="a-stat-val">{{ $totalEps }}</div>
|
||
<div class="a-stat-lbl">Bölüm</div>
|
||
</div>
|
||
</div>
|
||
<div class="a-stat-card">
|
||
<div class="a-stat-icon purple"><i class="bi bi-layers"></i></div>
|
||
<div class="a-stat-info">
|
||
<div class="a-stat-val">{{ $anime->seasons->count() }}</div>
|
||
<div class="a-stat-lbl">Sezon</div>
|
||
</div>
|
||
</div>
|
||
@if($anime->release_year)
|
||
<div class="a-stat-card">
|
||
<div class="a-stat-icon muted"><i class="bi bi-calendar3"></i></div>
|
||
<div class="a-stat-info">
|
||
<div class="a-stat-val">{{ $anime->release_year }}</div>
|
||
<div class="a-stat-lbl">Yıl</div>
|
||
</div>
|
||
</div>
|
||
@endif
|
||
@if($anime->studio)
|
||
<div class="a-stat-card">
|
||
<div class="a-stat-icon pink"><i class="bi bi-building"></i></div>
|
||
<div class="a-stat-info">
|
||
<div class="a-stat-val" style="font-size:.82rem;line-height:1.3">{{ $anime->studio }}</div>
|
||
<div class="a-stat-lbl">Stüdyo</div>
|
||
</div>
|
||
</div>
|
||
@endif
|
||
</div>
|
||
|
||
{{-- Description --}}
|
||
@if($anime->description)
|
||
<div class="a-desc-wrap">
|
||
<p class="a-desc clamped" id="adesc">{{ $anime->description }}</p>
|
||
<button class="a-desc-btn" id="adesc-btn" onclick="toggleDesc()">
|
||
<i class="bi bi-chevron-down" id="adesc-icon"></i> Devamını Oku
|
||
</button>
|
||
</div>
|
||
@endif
|
||
|
||
{{-- Tabs --}}
|
||
<div class="a-tabs" id="tabs">
|
||
<button class="a-tab on" data-tab="ep" onclick="showTab('ep',this)"><i class="bi bi-collection-play"></i>Bölümler</button>
|
||
<button class="a-tab" data-tab="info" id="tab-btn-info" onclick="showTab('info',this)"><i class="bi bi-info-circle"></i>Bilgiler</button>
|
||
@if($related->count())<button class="a-tab" data-tab="rel" onclick="showTab('rel',this)"><i class="bi bi-grid-3x3-gap"></i>Benzerler</button>@endif
|
||
@auth
|
||
<button class="a-tab" data-tab="ai-sim" onclick="showTab('ai-sim',this);loadAiSimilar()" style="color:var(--accent3)"><i class="bi bi-stars"></i>AI Önerileri</button>
|
||
@else
|
||
<button class="a-tab" onclick="showLoginPrompt()" style="color:var(--accent3);opacity:.55"><i class="bi bi-stars"></i>AI Önerileri <i class="bi bi-lock-fill" style="font-size:.65rem;margin-left:2px"></i></button>
|
||
@endauth
|
||
</div>
|
||
|
||
{{-- Episodes --}}
|
||
<div class="tab-pane on" id="tab-ep">
|
||
@if($anime->seasons->count() > 1)
|
||
<div class="season-tabs" id="stabs">
|
||
@foreach($anime->seasons as $s)
|
||
<button class="s-btn {{ $loop->first ? 'on' : '' }}" data-s="{{ $s->season_number }}" onclick="switchSeason({{ $s->season_number }},this)">
|
||
{{ $s->season_number }}. Sezon
|
||
<span style="opacity:.45;font-weight:400;margin-left:3px">({{ $s->episodes->count() }})</span>
|
||
</button>
|
||
@endforeach
|
||
</div>
|
||
@endif
|
||
|
||
@foreach($anime->seasons as $s)
|
||
<div class="ep-list" id="s{{ $s->season_number }}" style="{{ !$loop->first ? 'display:none' : '' }}">
|
||
@forelse($s->episodes as $ep)
|
||
<a href="{{ route('watch',[$anime->slug,$s->season_number,$ep->episode_number]) }}" class="ep-card">
|
||
<div class="ep-card-thumb">
|
||
@if($ep->thumbnailUrl)<img src="{{ $ep->thumbnailUrl }}" alt="" loading="lazy">
|
||
@elseif($anime->coverUrl)<img src="{{ $anime->coverUrl }}" alt="" loading="lazy">
|
||
@else<div class="no-thumb"><i class="bi bi-film"></i></div>@endif
|
||
<div class="ep-play-overlay"><i class="bi bi-play-circle-fill"></i></div>
|
||
<div class="ep-num-badge">{{ $ep->episode_number }}. Bölüm</div>
|
||
</div>
|
||
<div class="ep-card-body">
|
||
<div class="ep-card-num">S{{ str_pad($s->season_number,2,'0',STR_PAD_LEFT) }} · E{{ str_pad($ep->episode_number,2,'0',STR_PAD_LEFT) }}</div>
|
||
<div class="ep-card-title">{{ $ep->title ?: ($ep->episode_number.'. Bölüm') }}</div>
|
||
<div class="ep-card-meta">
|
||
@if($ep->duration)<span><i class="bi bi-clock me-1"></i>{{ $ep->duration_formatted }}</span>@endif
|
||
@if($ep->view_count)<span><i class="bi bi-eye me-1"></i>{{ number_format($ep->view_count) }}</span>@endif
|
||
</div>
|
||
</div>
|
||
</a>
|
||
@empty
|
||
<p style="color:rgba(255,255,255,.25);padding:24px 0;text-align:center">Bu sezonda henüz bölüm yok.</p>
|
||
@endforelse
|
||
</div>
|
||
@endforeach
|
||
</div>
|
||
|
||
{{-- Info --}}
|
||
<div class="tab-pane" id="tab-info">
|
||
<table class="info-table">
|
||
@if($anime->studio)<tr><td>Stüdyo</td><td>{{ $anime->studio }}</td></tr>@endif
|
||
@if($anime->release_year)<tr><td>Yıl</td><td>{{ $anime->release_year }}</td></tr>@endif
|
||
<tr><td>Tür</td><td>{{ $anime->type==='movie' ? 'Film' : 'Dizi' }}</td></tr>
|
||
<tr><td>Durum</td><td>{{ $anime->status==='ongoing' ? 'Devam Ediyor' : ($anime->status==='completed' ? 'Tamamlandı' : 'Yakında') }}</td></tr>
|
||
@if($anime->episode_count)<tr><td>Toplam Bölüm</td><td>{{ $anime->episode_count }}</td></tr>@endif
|
||
@if($anime->rating)<tr><td>Puan</td><td><span style="color:#fbbf24;font-weight:800">★ {{ number_format($anime->rating,1) }}</span> <span style="color:rgba(255,255,255,.3)">/ 10</span></td></tr>@endif
|
||
@if($anime->genres->count())<tr><td>Türler</td><td><div style="display:flex;flex-wrap:wrap;gap:5px;padding:4px 0">@foreach($anime->genres as $g)<a href="{{ route('genre',$g->slug) }}" class="ah-genre-chip">{{ $g->name }}</a>@endforeach</div></td></tr>@endif
|
||
@if($anime->mal_id)<tr><td>MAL ID</td><td style="color:rgba(255,255,255,.5)">{{ $anime->mal_id }}</td></tr>@endif
|
||
</table>
|
||
</div>
|
||
|
||
{{-- Related --}}
|
||
@if($related->count())
|
||
<div class="tab-pane" id="tab-rel">
|
||
<div class="rel-grid">
|
||
@foreach($related as $r)
|
||
<a href="{{ $r->detailUrl }}" class="a-card">
|
||
<div class="a-poster">
|
||
@if($r->coverUrl)<img src="{{ $r->coverUrl }}" alt="{{ $r->title }}" loading="lazy">
|
||
@else<div class="a-no-img"><i class="bi bi-image"></i></div>@endif
|
||
@if($r->rating)<span class="a-rating"><i class="bi bi-star-fill" style="font-size:.65rem"></i>{{ number_format($r->rating,1) }}</span>@endif
|
||
<div class="a-hover-play"><div class="play-circle"><i class="bi bi-play-fill"></i></div></div>
|
||
</div>
|
||
<div class="a-info">
|
||
<div class="a-title">{{ $r->title }}</div>
|
||
<div class="a-meta">{{ $r->release_year }}</div>
|
||
</div>
|
||
</a>
|
||
@endforeach
|
||
</div>
|
||
</div>
|
||
@endif
|
||
|
||
{{-- AI Similar --}}
|
||
@auth
|
||
<div class="tab-pane" id="tab-ai-sim">
|
||
<div id="ai-sim-wrap" style="padding:8px 0">
|
||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:20px;padding:18px 20px;background:linear-gradient(135deg,rgba(184,77,255,.08),rgba(0,245,255,.04));border:1px solid rgba(184,77,255,.18);border-radius:16px">
|
||
<div style="width:42px;height:42px;border-radius:12px;background:linear-gradient(135deg,var(--accent3),var(--accent));display:flex;align-items:center;justify-content:center;font-size:1.1rem;color:#fff;box-shadow:0 0 20px rgba(184,77,255,.35);flex-shrink:0"><i class="bi bi-stars"></i></div>
|
||
<div>
|
||
<div style="font-weight:700;color:#fff;font-size:.92rem">AI Benzer Öneri</div>
|
||
<div style="font-size:.76rem;color:rgba(255,255,255,.35);margin-top:2px">Bu animeye benzer alternatifleri yapay zeka analiz ediyor</div>
|
||
</div>
|
||
</div>
|
||
<div id="ai-sim-loader" style="display:flex;justify-content:center;align-items:center;gap:10px;padding:40px">
|
||
<div style="display:flex;gap:5px">
|
||
<div style="width:8px;height:8px;border-radius:50%;background:var(--accent3);animation:aip-b .9s ease-in-out infinite"></div>
|
||
<div style="width:8px;height:8px;border-radius:50%;background:var(--accent);animation:aip-b .9s .18s ease-in-out infinite"></div>
|
||
<div style="width:8px;height:8px;border-radius:50%;background:var(--accent2);animation:aip-b .9s .36s ease-in-out infinite"></div>
|
||
</div>
|
||
<span style="color:rgba(255,255,255,.3);font-size:.85rem">AI analiz yapıyor...</span>
|
||
</div>
|
||
<div class="rel-grid" id="ai-sim-grid" style="display:none"></div>
|
||
<div id="ai-sim-error" style="display:none;padding:20px;text-align:center;color:rgba(255,255,255,.3);font-size:.88rem"></div>
|
||
</div>
|
||
</div>
|
||
@endauth
|
||
|
||
</div>
|
||
|
||
{{-- FAQ Section (SEO + UX) --}}
|
||
@if(count($__faqItems) > 0)
|
||
<div class="section" style="padding-top:0;padding-bottom:48px">
|
||
<div style="max-width:860px;margin:0 auto">
|
||
<h2 class="ah-desc" style="font-family:var(--font-display);font-size:.82rem;text-transform:uppercase;letter-spacing:.1em;color:var(--accent2);font-weight:800;margin-bottom:18px">
|
||
<i class="bi bi-question-circle me-2"></i>{{ $anime->title }} Hakkında Sıkça Sorulan Sorular
|
||
</h2>
|
||
<div style="display:flex;flex-direction:column;gap:8px">
|
||
@foreach($__faqItems as $fq)
|
||
<details style="background:rgba(17,17,31,.7);border:1px solid rgba(0,245,255,.1);border-radius:10px;padding:0;overflow:hidden">
|
||
<summary style="padding:14px 18px;cursor:pointer;font-size:.88rem;font-weight:600;color:var(--text);list-style:none;display:flex;justify-content:space-between;align-items:center;gap:10px">
|
||
{{ $fq['q'] }}
|
||
<i class="bi bi-chevron-down" style="flex-shrink:0;font-size:.75rem;color:var(--accent2);transition:transform .2s"></i>
|
||
</summary>
|
||
<div style="padding:0 18px 14px;font-size:.86rem;color:var(--text2);line-height:1.65;border-top:1px solid rgba(0,245,255,.07)">
|
||
<p style="margin:12px 0 0">{{ $fq['a'] }}</p>
|
||
</div>
|
||
</details>
|
||
@endforeach
|
||
</div>
|
||
</div>
|
||
</div>
|
||
@endif
|
||
|
||
@endsection
|
||
{{-- Login prompt modal (misafirler için) --}}
|
||
<div id="login-prompt" class="login-prompt-overlay" style="display:none" onclick="if(event.target===this)this.style.display='none'">
|
||
<div class="login-prompt-box">
|
||
<div style="font-size:2.5rem;margin-bottom:12px">🔒</div>
|
||
<h3>Bu özellik üyelere özel</h3>
|
||
<p>AI önerileri, izleme listesi ve daha fazlası için giriş yapman yeterli.</p>
|
||
<a href="{{ route('frontend.login') }}" class="lp-btn lp-btn-primary">Giriş Yap</a>
|
||
<a href="{{ route('frontend.register') }}" class="lp-btn lp-btn-secondary">Kayıt Ol</a>
|
||
</div>
|
||
</div>
|
||
|
||
@push('scripts')
|
||
<script>
|
||
// Fade in backdrop
|
||
setTimeout(()=>document.getElementById('a-backdrop')?.classList.add('on'),100);
|
||
|
||
function showLoginPrompt() {
|
||
document.getElementById('login-prompt').style.display = 'flex';
|
||
}
|
||
|
||
// ── Follow ───────────────────────────────────────────────────────────────────
|
||
const CSRF = document.querySelector('meta[name=csrf-token]')?.content||'';
|
||
|
||
async function toggleFollow() {
|
||
const btn = document.getElementById('follow-btn');
|
||
const icon = document.getElementById('follow-icon');
|
||
const lbl = document.getElementById('follow-label');
|
||
btn.disabled = true;
|
||
try {
|
||
const res = await fetch('/anime/{{ $anime->slug }}/follow', {
|
||
method:'POST',
|
||
headers:{'Content-Type':'application/json','X-CSRF-TOKEN':CSRF},
|
||
body:'{}'
|
||
});
|
||
const d = await res.json();
|
||
if (d.following) {
|
||
icon.className = 'bi bi-bell-fill';
|
||
lbl.textContent = 'Takiptesin';
|
||
btn.classList.add('active-fl');
|
||
} else {
|
||
icon.className = 'bi bi-bell';
|
||
lbl.textContent = 'Takip Et';
|
||
btn.classList.remove('active-fl');
|
||
}
|
||
} catch(e) {}
|
||
btn.disabled = false;
|
||
}
|
||
|
||
// ── Watchlist ────────────────────────────────────────────────────────────────
|
||
|
||
function toggleWlMenu(){
|
||
const menu = document.getElementById('wl-menu');
|
||
const isOpen = menu.style.display === 'block';
|
||
if (isOpen) { menu.style.display = 'none'; return; }
|
||
|
||
const btn = document.getElementById('wl-btn');
|
||
const rect = btn.getBoundingClientRect();
|
||
|
||
// Önce göster (boyutu hesaplamak için)
|
||
menu.style.visibility = 'hidden';
|
||
menu.style.display = 'block';
|
||
const menuH = menu.offsetHeight;
|
||
const menuW = menu.offsetWidth;
|
||
menu.style.visibility = '';
|
||
|
||
// Alt boşluk yeterli mi?
|
||
const spaceBelow = window.innerHeight - rect.bottom;
|
||
if (spaceBelow >= menuH + 8) {
|
||
menu.style.top = (rect.bottom + 6) + 'px';
|
||
} else {
|
||
menu.style.top = (rect.top - menuH - 6) + 'px';
|
||
}
|
||
|
||
// Sağdan taşmasın
|
||
const left = Math.min(rect.left, window.innerWidth - menuW - 8);
|
||
menu.style.left = Math.max(8, left) + 'px';
|
||
}
|
||
document.addEventListener('click', e => {
|
||
if (!document.getElementById('wl-wrap')?.contains(e.target)) {
|
||
document.getElementById('wl-menu').style.display='none';
|
||
}
|
||
});
|
||
|
||
async function setWatchlist(status) {
|
||
document.getElementById('wl-menu').style.display='none';
|
||
const res = await fetch('{{ route("watchlist.toggle", $anime) }}', {
|
||
method:'POST',
|
||
headers:{'Content-Type':'application/json','X-CSRF-TOKEN':CSRF},
|
||
body: JSON.stringify({status})
|
||
});
|
||
const data = await res.json();
|
||
const btn = document.getElementById('wl-btn');
|
||
if (data.in_list) {
|
||
btn.innerHTML = `<i class="bi bi-bookmark-fill"></i> <span class="btn-lbl">${data.status_label}</span>`;
|
||
btn.classList.add('active-wl');
|
||
} else {
|
||
btn.innerHTML = `<i class="bi bi-bookmark-plus"></i> <span class="btn-lbl">Listeye Ekle</span>`;
|
||
btn.classList.remove('active-wl');
|
||
}
|
||
if (data.achievements?.length) {
|
||
data.achievements.forEach(a => showAchievement(a));
|
||
}
|
||
}
|
||
|
||
// ── Anime Puanlama ───────────────────────────────────────────────────────────
|
||
async function rateAnime(rating) {
|
||
const res = await fetch('{{ route("anime.rate", $anime) }}', {
|
||
method:'POST',
|
||
headers:{'Content-Type':'application/json','X-CSRF-TOKEN':CSRF},
|
||
body: JSON.stringify({rating})
|
||
});
|
||
const data = await res.json();
|
||
// Yıldızları güncelle
|
||
document.querySelectorAll('.star-btn').forEach(b => {
|
||
b.classList.toggle('on', parseInt(b.dataset.r) <= rating);
|
||
});
|
||
const lbl = document.getElementById('my-rating-lbl');
|
||
if (lbl) lbl.textContent = `${rating}/10 verdin`;
|
||
else {
|
||
const wrap = document.getElementById('rating-wrap');
|
||
if (wrap) {
|
||
const s = document.createElement('span');
|
||
s.id='my-rating-lbl';
|
||
s.style='font-size:.78rem;color:var(--accent);margin-left:8px';
|
||
s.textContent=`${rating}/10 verdin`;
|
||
wrap.appendChild(s);
|
||
}
|
||
}
|
||
}
|
||
|
||
// ── Paylaş ───────────────────────────────────────────────────────────────────
|
||
function shareAnime() {
|
||
const title = '{{ addslashes($anime->title) }}';
|
||
const url = window.location.href;
|
||
const text = `${title} — Animexe'de ücretsiz izle!`;
|
||
if (navigator.share) {
|
||
navigator.share({ title, text, url }).catch(() => {});
|
||
return;
|
||
}
|
||
// Fallback: share modal
|
||
const overlay = document.createElement('div');
|
||
overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.78);z-index:9999;display:flex;align-items:center;justify-content:center;padding:16px;backdrop-filter:blur(8px)';
|
||
overlay.innerHTML = `
|
||
<div style="background:#0e0e1a;border:1px solid rgba(255,255,255,.12);border-radius:20px;width:100%;max-width:360px;overflow:hidden">
|
||
<div style="padding:16px 20px;border-bottom:1px solid rgba(255,255,255,.07);display:flex;justify-content:space-between;align-items:center">
|
||
<span style="font-size:.95rem;font-weight:700;color:#fff"><i class="bi bi-share" style="color:var(--accent2)"></i> Paylaş</span>
|
||
<button onclick="this.closest('[style*=fixed]').remove()" style="background:none;border:none;color:rgba(255,255,255,.4);font-size:1.1rem;cursor:pointer"><i class="bi bi-x-lg"></i></button>
|
||
</div>
|
||
<div style="padding:20px;display:flex;gap:12px;flex-wrap:wrap;justify-content:center">
|
||
<a href="https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&url=${encodeURIComponent(url)}" target="_blank" rel="noopener" style="display:flex;flex-direction:column;align-items:center;gap:6px;padding:14px 20px;border-radius:12px;background:rgba(29,161,242,.1);border:1px solid rgba(29,161,242,.25);color:#1da1f2;text-decoration:none;font-size:.75rem;font-weight:700;transition:background .15s" onmouseover="this.style.background='rgba(29,161,242,.2)'" onmouseout="this.style.background='rgba(29,161,242,.1)'">
|
||
<i class="bi bi-twitter-x" style="font-size:1.4rem"></i> X / Twitter
|
||
</a>
|
||
<a href="https://wa.me/?text=${encodeURIComponent(text + '\n' + url)}" target="_blank" rel="noopener" style="display:flex;flex-direction:column;align-items:center;gap:6px;padding:14px 20px;border-radius:12px;background:rgba(37,211,102,.1);border:1px solid rgba(37,211,102,.25);color:#25d366;text-decoration:none;font-size:.75rem;font-weight:700;transition:background .15s" onmouseover="this.style.background='rgba(37,211,102,.2)'" onmouseout="this.style.background='rgba(37,211,102,.1)'">
|
||
<i class="bi bi-whatsapp" style="font-size:1.4rem"></i> WhatsApp
|
||
</a>
|
||
<button onclick="navigator.clipboard?.writeText('${url.replace(/'/g,"\\'").replace(/\\/g,'\\\\').replace(/"/g,'"')}').then(()=>{ if(window.showToast) showToast('Link kopyalandı!','success'); this.closest('[style*=fixed]').remove(); })" style="display:flex;flex-direction:column;align-items:center;gap:6px;padding:14px 20px;border-radius:12px;background:rgba(0,245,255,.08);border:1px solid rgba(0,245,255,.22);color:var(--accent2);cursor:pointer;font-size:.75rem;font-weight:700;transition:background .15s" onmouseover="this.style.background='rgba(0,245,255,.16)'" onmouseout="this.style.background='rgba(0,245,255,.08)'">
|
||
<i class="bi bi-link-45deg" style="font-size:1.4rem"></i> Link Kopyala
|
||
</button>
|
||
</div>
|
||
</div>
|
||
`;
|
||
document.body.appendChild(overlay);
|
||
overlay.addEventListener('click', e => { if (e.target === overlay) overlay.remove(); });
|
||
}
|
||
|
||
// ── Achievement popup ────────────────────────────────────────────────────────
|
||
function showAchievement(ach) {
|
||
const div = document.createElement('div');
|
||
div.className = 'ach-popup';
|
||
div.innerHTML = `<i class="bi ${ach.icon} ach-icon" style="color:${ach.color}"></i><div><div class="ach-title">🏆 Başarım Kazandın!</div><div class="ach-name">${ach.title}</div></div>`;
|
||
document.body.appendChild(div);
|
||
setTimeout(() => div.remove(), 4000);
|
||
}
|
||
|
||
function showTab(tab, btn) {
|
||
document.querySelectorAll('.a-tab').forEach(t=>t.classList.remove('on'));
|
||
document.querySelectorAll('.tab-pane').forEach(p=>p.classList.remove('on'));
|
||
if(btn) btn.classList.add('on');
|
||
else document.querySelector(`.a-tab[data-tab="${tab}"]`)?.classList.add('on');
|
||
document.getElementById('tab-'+tab)?.classList.add('on');
|
||
}
|
||
|
||
function switchSeason(n,btn){
|
||
document.querySelectorAll('[id^="s"]').forEach(el=>{ if(/^s\d+$/.test(el.id)) el.style.display='none'; });
|
||
document.querySelectorAll('.s-btn').forEach(b=>b.classList.remove('on'));
|
||
document.getElementById('s'+n).style.display='flex';
|
||
btn.classList.add('on');
|
||
}
|
||
|
||
function toggleDesc(){
|
||
const d=document.getElementById('adesc'), b=document.getElementById('adesc-btn'), ic=document.getElementById('adesc-icon');
|
||
d.classList.toggle('clamped');
|
||
const collapsed = d.classList.contains('clamped');
|
||
b.innerHTML = `<i class="bi bi-chevron-${collapsed?'down':'up'}" id="adesc-icon"></i> ${collapsed?'Devamını Oku':'Daha Az Göster'}`;
|
||
}
|
||
|
||
// Hash-based tab: #tab-info
|
||
if(location.hash==='#tab-info') setTimeout(()=>showTab('info', document.querySelector('.a-tab[data-tab="info"]')),50);
|
||
|
||
@auth
|
||
// ── AI Benzer Animeler ────────────────────────────────────────────────────────
|
||
let aiSimLoaded = false;
|
||
async function loadAiSimilar() {
|
||
if (aiSimLoaded) return;
|
||
const loader = document.getElementById('ai-sim-loader');
|
||
const grid = document.getElementById('ai-sim-grid');
|
||
const errEl = document.getElementById('ai-sim-error');
|
||
const csrf = document.querySelector('meta[name=csrf-token]')?.content || '';
|
||
|
||
try {
|
||
const res = await fetch('{{ route("ai.similar") }}', {
|
||
method: 'POST',
|
||
headers: {'Content-Type':'application/json','X-CSRF-TOKEN':csrf},
|
||
body: JSON.stringify({anime_id: {{ $anime->id }} })
|
||
});
|
||
const data = await res.json();
|
||
loader.style.display = 'none';
|
||
const items = data.similar || [];
|
||
if (!items.length) {
|
||
errEl.textContent = 'Şu an benzer öneri bulunamadı.';
|
||
errEl.style.display = 'block';
|
||
} else {
|
||
grid.style.display = '';
|
||
items.forEach(a => {
|
||
grid.innerHTML += `<a href="/anime/${a.slug}" class="a-card">
|
||
<div class="a-poster">
|
||
${a.cover ? `<img src="${a.cover}" alt="" loading="lazy">` : '<div class="a-no-img"><i class="bi bi-image"></i></div>'}
|
||
${a.rating ? `<span class="a-rating"><i class="bi bi-star-fill" style="font-size:.65rem"></i>${parseFloat(a.rating).toFixed(1)}</span>` : ''}
|
||
<div class="a-hover-play"><div class="play-circle"><i class="bi bi-play-fill"></i></div></div>
|
||
${a.reason ? `<div style="position:absolute;bottom:0;left:0;right:0;padding:6px 8px;background:linear-gradient(to top,rgba(0,0,0,.85),transparent);font-size:.65rem;color:rgba(255,255,255,.8);line-height:1.35">${esc(a.reason)}</div>` : ''}
|
||
</div>
|
||
<div class="a-info">
|
||
<div class="a-title">${esc(a.title)}</div>
|
||
<div class="a-meta">${a.type==='movie'?'Film':'Dizi'}</div>
|
||
</div>
|
||
</a>`;
|
||
});
|
||
}
|
||
aiSimLoaded = true;
|
||
} catch(e) {
|
||
loader.style.display = 'none';
|
||
errEl.textContent = 'AI servisi bağlantı hatası.';
|
||
errEl.style.display = 'block';
|
||
}
|
||
}
|
||
function esc(s){ return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"'); }
|
||
@endauth
|
||
|
||
// ── Zaman Kapsülü Modal ───────────────────────────────────────────────────────
|
||
function openCapsuleModal() {
|
||
document.getElementById('capsule-modal').classList.add('on');
|
||
}
|
||
function closeCapsuleModal() {
|
||
document.getElementById('capsule-modal').classList.remove('on');
|
||
}
|
||
async function submitCapsule() {
|
||
const msg = document.getElementById('cap-msg').value.trim();
|
||
const dt = document.getElementById('cap-date').value;
|
||
const err = document.getElementById('cap-err');
|
||
err.style.display = 'none';
|
||
if (msg.length < 5) { err.textContent = 'Mesaj en az 5 karakter olmalı.'; err.style.display = 'block'; return; }
|
||
if (!dt) { err.textContent = 'Açılış tarihi seçin.'; err.style.display = 'block'; return; }
|
||
const CSRF = document.querySelector('meta[name="csrf-token"]')?.content ?? '';
|
||
const r = await fetch('/kapsul', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': CSRF, 'Accept': 'application/json' },
|
||
body: JSON.stringify({ anime_id: {{ $anime->id }}, message: msg, unlock_at: dt }),
|
||
});
|
||
const d = await r.json();
|
||
if (d.ok) {
|
||
closeCapsuleModal();
|
||
document.getElementById('cap-msg').value = '';
|
||
// toast mesajı
|
||
const t = document.createElement('div');
|
||
t.textContent = '⏳ Kapsül oluşturuldu!';
|
||
t.style.cssText = 'position:fixed;bottom:24px;left:50%;transform:translateX(-50%);background:#1a1a2e;border:1px solid rgba(167,139,250,.3);border-radius:12px;padding:12px 20px;color:#fff;font-size:.88rem;z-index:9999;pointer-events:none';
|
||
document.body.appendChild(t);
|
||
setTimeout(() => t.remove(), 3000);
|
||
} else {
|
||
err.textContent = d.error || 'Hata oluştu.';
|
||
err.style.display = 'block';
|
||
}
|
||
}
|
||
</script>
|
||
@endpush
|
||
|
||
{{-- Zaman Kapsülü Modal --}}
|
||
@auth
|
||
<div id="capsule-modal" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.75);z-index:9000;backdrop-filter:blur(8px);align-items:center;justify-content:center;padding:16px" onclick="if(event.target===this)closeCapsuleModal()">
|
||
<style>#capsule-modal.on{display:flex}</style>
|
||
<div style="background:#0e0e1a;border:1px solid rgba(167,139,250,.25);border-radius:20px;width:100%;max-width:440px;overflow:hidden">
|
||
<div style="padding:16px 20px;border-bottom:1px solid rgba(255,255,255,.07);display:flex;justify-content:space-between;align-items:center">
|
||
<h5 style="margin:0;font-size:.95rem;color:#fff">⏳ Zaman Kapsülü Bırak</h5>
|
||
<button onclick="closeCapsuleModal()" style="background:none;border:none;color:rgba(255,255,255,.4);font-size:1.1rem;cursor:pointer"><i class="bi bi-x-lg"></i></button>
|
||
</div>
|
||
<div style="padding:20px">
|
||
<p style="font-size:.82rem;color:rgba(255,255,255,.45);margin-bottom:16px">
|
||
Gelecekteki kendine mesaj bırak. Seçtiğin tarihte <a href="{{ route('capsules.index') }}" style="color:#a78bfa">kapsüllerim</a> sayfasında açılır.
|
||
</p>
|
||
<div style="font-size:.72rem;font-weight:700;color:rgba(167,139,250,.7);text-transform:uppercase;letter-spacing:.07em;margin-bottom:6px">Mesajın</div>
|
||
<textarea id="cap-msg" rows="4" maxlength="1000" placeholder="Gelecekteki kendine ne söylemek istersin?"
|
||
style="width:100%;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.1);border-radius:10px;padding:10px 14px;color:#fff;font-size:.88rem;font-family:inherit;resize:none;outline:none;margin-bottom:14px;box-sizing:border-box"></textarea>
|
||
<div style="font-size:.72rem;font-weight:700;color:rgba(167,139,250,.7);text-transform:uppercase;letter-spacing:.07em;margin-bottom:6px">Açılış Tarihi (en az 30 gün sonra)</div>
|
||
<input type="date" id="cap-date" min="{{ now()->addDays(30)->format('Y-m-d') }}"
|
||
style="width:100%;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.1);border-radius:10px;padding:10px 14px;color:#fff;font-size:.88rem;font-family:inherit;outline:none;margin-bottom:14px;box-sizing:border-box">
|
||
<div id="cap-err" style="color:#ff4444;font-size:.78rem;margin-bottom:10px;display:none"></div>
|
||
<button onclick="submitCapsule()" style="width:100%;padding:12px;border-radius:12px;border:none;background:rgba(167,139,250,.2);color:#a78bfa;font-weight:700;font-size:.9rem;cursor:pointer;font-family:inherit;transition:background .15s" onmouseover="this.style.background='rgba(167,139,250,.35)'" onmouseout="this.style.background='rgba(167,139,250,.2)'">
|
||
⏳ Kapsülü Kilitle
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
@endauth
|