{% include sidebar.html %} -
+
+ + + {% if page.title %}{% endif %}
-
+
{{ content }}
diff --git a/_layouts/post.html b/_layouts/post.html new file mode 100644 index 00000000000..94c93f4f29b --- /dev/null +++ b/_layouts/post.html @@ -0,0 +1,168 @@ +--- +layout: default +--- + +
+ + {% if page.excerpt %}{% endif %} + {% if page.date %}{% endif %} + {% if page.author %}{% endif %} + + +
+
+

{{ page.title }}

+ + + + {% if page.tags %} + + {% endif %} + + {% if page.excerpt %} +

{{ page.excerpt }}

+ {% endif %} +
+ +
+
+ {{ content }} +
+
+
+ + {% if page.tags %} + + {% endif %} + + + {% if site.posts.size > 1 %} + + {% endif %} + + + + + +
+ + Back to Blog + +
+
diff --git a/_pages/about.md b/_pages/about.md index 1e8935ec9ca..a5c67411bec 100644 --- a/_pages/about.md +++ b/_pages/about.md @@ -8,51 +8,318 @@ redirect_from: - /about.html --- -{% if site.google_scholar_stats_use_cdn %} -{% assign gsDataBaseUrl = "https://cdn.jsdelivr.net/gh/" | append: site.repository | append: "@" %} -{% else %} -{% assign gsDataBaseUrl = "https://raw.githubusercontent.com/" | append: site.repository | append: "/" %} -{% endif %} -{% assign url = gsDataBaseUrl | append: "google-scholar-stats/gs_data_shieldsio.json" %} - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ornare aliquet ipsum, ac tempus justo dapibus sit amet. Suspendisse condimentum, libero vel tempus mattis, risus risus vulputate libero, elementum fermentum mi neque vel nisl. Maecenas facilisis maximus dignissim. Curabitur mattis vulputate dui, tincidunt varius libero luctus eu. Mauris mauris nulla, scelerisque eget massa id, tincidunt congue felis. Sed convallis tempor ipsum rhoncus viverra. Pellentesque nulla orci, accumsan volutpat fringilla vitae, maximus sit amet tortor. Aliquam ultricies odio ut volutpat scelerisque. Donec nisl nisl, porttitor vitae pharetra quis, fringilla sed mi. Fusce pretium dolor ut aliquam consequat. Cras volutpat, tellus accumsan mattis molestie, nisl lacus tempus massa, nec malesuada tortor leo vel quam. Aliquam vel ex consectetur, vehicula leo nec, efficitur eros. Donec convallis non urna quis feugiat. +I am a final-year undergraduate student pursuing a BSc (Hons) in Computer Science and Engineering at the **University of Dhaka**, Bangladesh, with a CGPA of **3.84/4.00**. My research interests lie at the intersection of **high-performance machine learning systems**, **large language models(LLMs)** and **natural language processing**, with applications in large-scale scientific data analysis. -My research interest includes neural machine translation and computer vision. I have published more than 100 papers at the top international AI conferences with total google scholar citations 260000+ (You can also use google scholar badge ). +Currently, I am working as a **Research Assistant** under the supervision of [**Dr. Muhammad Ibrahim**](https://www.cse.du.ac.bd/profile/?faculty=MI) at the University of Dhaka, where I am developing large-scale Bangla QA datasets and fine-tuning transformer-based models for question answering systems. I am also an active member of the **DU_Caffeine Team**, contributing to winning multiple national hackathons through the development and deployment of ML solutions. +I am passionate about building efficient, scalable systems that bridge the gap between cutting-edge research and real-world applications. # 🔥 News -- *2022.02*:  🎉🎉 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ornare aliquet ipsum, ac tempus justo dapibus sit amet. -- *2022.02*:  🎉🎉 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ornare aliquet ipsum, ac tempus justo dapibus sit amet. -# 📝 Publications +
    +
  • + 2026.04 + Selected at NUS Young Fellowship Programme 2026 +
  • +
  • + 2025.12 + Champion at Solvio AI Hackathon with Project ZeroBin: AI-Driven Waste Management Platform +
  • +
  • + 2025.11 + Top 20 at VisionX Project Showcasing 2025 +
  • +
  • + 2025.09 + 7th Place at InnovateX Hackathon, BUBT +
  • +
  • + 2025.07 + Completed Summer School on Energy Data Analytics at IIT Bombay, India +
  • +
  • + 2025.03 + Started working as a Research Assistant at the University of Dhaka under Dr. Muhammad Ibrahim +
  • +
+ +# 💼 Experience + +
+
+
+
Research Assistant
+
University of Dhaka
+
+
+
Mar 2025 – Feb 2026
+
Supervisor: Dr. Muhammad Ibrahim
+
+
+
    +
  • Developed a large-scale Bangla QA dataset with 94,000 QA pairs and 210M tokens, implementing an automated pipeline for document extraction, segmentation, and QA generation
  • +
  • Fine-tuned Qwen-2.5-7B using PyTorch, PEFT LoRA, and Chain-of-Thought prompting for parameter-efficient large model training
  • +
  • Implemented fine training for transformer-based extractive QA models including BERT, RoBERTa, and ELECTRA
  • +
  • Benchmarked generative vs. extractive QA systems using BLEU, F1, and Exact Match metrics on large-scale datasets
  • +
+
+ +
+
+
+
Machine Learning Engineer
+
DU_Caffeine Team, University of Dhaka
+
+
+
Sep 2025 – Present
+
+
+
    +
  • Core ML team member, developing and deploying ML solutions across 7+ national hackathons
  • +
  • Built ML systems including computer vision, NLP models, and time-series forecasting pipelines
  • +
  • Engineered scalable deployments using FastAPI, Docker, and cloud infrastructure
  • +
  • Awards: Champion – Solvio AI Hackathon; Top 20 – VisionX; 7th Place - InnovativeX
  • +
+
+ + + +# 🎓 Education + +
+
+
+
BSc (Hons) in Computer Science and Engineering
+
University of Dhaka, Bangladesh
+
2022 – Present
+
+
+
CGPA: 3.84/4.00
+
+
+ +
+
Relevant coursework
+
+ Machine Learning + Artificial Intelligence + Data Structures & Algorithms + Parallel & Distributed Systems + Computer Architecture + Operating Systems + Database Systems +
+
+
+ +
+
+
+
Higher Secondary Certificate (Science)
+
Notre Dame College, Dhaka
+
2018 – 2020
+
+
+
GPA: 5.00/5.00 (Scholarship)
+
+
+
+ +
+
+
+
Secondary School Certificate (Science)
+
B.M. Union School, Bandar
+
2013 – 2018
+
+
+
GPA: 5.00/5.00 (Scholarship)
+
+
+
+ +# 🎓 Summer Programme + +
+
+
+
Indian Institute of Technology (IIT) Bombay, India
+
Energy Data Analytics
+
July 2025
+
+
+ +

Completed intensive coursework on large-scale energy-sector datasets. Applied machine learning and time-series analysis to extract actionable insights from real-world scientific data (ASHRAE Building Energy Dataset).

+
+ +# 🚀 Selected Projects + +
+
+Sep-Dec 2025 + +**ZeroBin — AI-Driven Waste Management Platform** -
CVPR 2016
sym
+*Machine Learning Engineer & Team Lead* + + Live Demo GitHub 🤗 Hugging Face + +- Led 4-member team to design and deploy ML-driven solutions for smart city waste management +- Developed **LightGBM geospatial prediction** and **LSTM time-series forecasting** models for resource optimization +- Fine-tuned Onnubuti AI sentiment analysis model achieving **94.5% accuracy** +- Deployed scalable inference system with FastAPI, Docker, and RESTful APIs +- **🏆 Champion** at Solvio AI Hackathon (2025) + +
+
+ +
+Dec 2025-Jan 2026 -[Deep Residual Learning for Image Recognition](https://openaccess.thecvf.com/content_cvpr_2016/papers/He_Deep_Residual_Learning_CVPR_2016_paper.pdf) +**Distributed Machine Learning System with MPI & OpenMP** -**Kaiming He**, Xiangyu Zhang, Shaoqing Ren, Jian Sun + GitHub + +- Developed a distributed ML system using **C, MPI, and OpenMP** with synchronized gradient updates across 8 parallel processes +- Built a low-latency inference pipeline integrating MPI with **FastAPI backend** and **Next.js frontend** for real-time predictions +- Implemented parallelized matrix multiplication with OpenMP to enable multi-linear regression -[**Project**](https://scholar.google.com/citations?view_op=view_citation&hl=zh-CN&user=DhtAFkwAAAAJ&citation_for_view=DhtAFkwAAAAJ:ALROH1vI_8AC) -- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ornare aliquet ipsum, ac tempus justo dapibus sit amet.
-- [Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ornare aliquet ipsum, ac tempus justo dapibus sit amet](https://github.com), A, B, C, **CVPR 2020** -# 🎖 Honors and Awards -- *2021.10* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ornare aliquet ipsum, ac tempus justo dapibus sit amet. -- *2021.09* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ornare aliquet ipsum, ac tempus justo dapibus sit amet. +
+
+Oct 2024-Jan 2025 -# 📖 Educations -- *2019.06 - 2022.04 (now)*, Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ornare aliquet ipsum, ac tempus justo dapibus sit amet. -- *2015.09 - 2019.06*, Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ornare aliquet ipsum, ac tempus justo dapibus sit amet. +**Flash — Tutorial Recommendation Platform** -# 💬 Invited Talks -- *2021.06*, Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ornare aliquet ipsum, ac tempus justo dapibus sit amet. -- *2021.03*, Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ornare aliquet ipsum, ac tempus justo dapibus sit amet. \| [\[video\]](https://github.com/) + GitHub -# 💻 Internships -- *2019.05 - 2020.02*, [Lorem](https://github.com/), China. \ No newline at end of file +- Implemented content-based recommendation system using **TF-IDF and cosine similarity** +- Built full-stack application for personalized tutorial recommendations + +
+
+ + + +# 🎖 Awards & Achievements + +
+ 2025 + 🏆 + Champion — Solvio AI Hackathon +
+
+ 2025 + 🚀 + Top 20 — VisionX Project Showcasing, University of Dhaka +
+
+ 2025 + 🏅 + Top 10 — S. N. Bose National IT Hackathon, University of Dhaka +
+
+ 2025 + 🎯 + 7th Place — Inter-University National Hackathon, Green University of Bangladesh +
+
+ 2025 + 💡 + 7th Place — InnovativeX Hackathon 2025, Bangladesh University of Business and Technology (BUBT) +
+
+ 2024 + 🌟 + Top 10 — CSE Carnival Hackathon, Shahjalal University of Science and Technology (SUST) +
+ +# 💻 Technical Skills + +
+Machine Learning & Deep Learning +PyTorch +TensorFlow +Keras +scikit-learn +XGBoost +LightGBM +Optuna +
+ +
+Natural Language Processing +Transformers +BERT +RoBERTa +ELECTRA +Qwen +LoRA +QLoRA +PEFT +Hugging Face +
+ +
+High-Performance Computing +MPI +OpenMP +Parallel Computing +CUDA +
+ +
+Data Science & Analysis +NumPy +Pandas +Matplotlib +Seaborn +Feature Engineering +
+ +
+Deployment & MLOps +FastAPI +Docker +REST APIs +CI/CD +Hugging Face Hub +
+ +
+Programming Languages +Python +C +C++ +SQL +JavaScript +
+ +
+Tools & Platforms +Git +GitHub +Linux +LaTeX +Jupyter +VS Code +
+ +# 📫 Contact + +
+

I am actively seeking opportunities for graduate studies and research positions in machine learning, distributed systems, and natural language processing.

+

Feel free to reach out — I'd love to connect!

+ + +
diff --git a/_pages/blog.md b/_pages/blog.md new file mode 100644 index 00000000000..7a55e55d783 --- /dev/null +++ b/_pages/blog.md @@ -0,0 +1,146 @@ +--- +layout: default +title: Blog +permalink: /blog/ +--- + +
+

{{ page.title }}

+

I love to write about programming, machine learning, NLP, LLMs and things that motivates me.

+ Read more on Medium → +
+ +
+ +
+ +
+ + {% assign all_tags = "" | split: "," %} + {% for post in site.posts %} + {% if post.tags %} + {% for tag in post.tags %} + {% unless all_tags contains tag %} + {% assign all_tags = all_tags | push: tag %} + {% endunless %} + {% endfor %} + {% endif %} + {% endfor %} + {% assign sorted_tags = all_tags | sort %} + {% for tag in sorted_tags %} + + {% endfor %} +
+
+ + +
+ {% if site.posts.size == 0 %} +
+ +

No posts yet

+

Check back soon for insights on ML, AI, and distributed systems!

+
+ {% else %} + {% for post in site.posts %} +
+
+

+ {{ post.title }} +

+
+ + + + {% if post.excerpt %} +

{{ post.excerpt }}

+ {% endif %} + + {% if post.tags %} + + {% endif %} + + + Read More + +
+ {% endfor %} + {% endif %} +
+
+ + diff --git a/_posts/2025-01-15-transformers-explained.md b/_posts/2025-01-15-transformers-explained.md new file mode 100644 index 00000000000..70fac1a59c0 --- /dev/null +++ b/_posts/2025-01-15-transformers-explained.md @@ -0,0 +1,86 @@ +--- +layout: post +title: "Transformers Explained: From Self-Attention to Modern LLMs" +date: 2025-01-15 +tags: [NLP, Deep Learning, Transformers, Machine Learning] +excerpt: "A comprehensive guide to understanding the transformer architecture, self-attention mechanisms, and their evolution into modern large language models." +--- + +## Introduction + +The transformer architecture, introduced by Vaswani et al. in 2017 with the paper "Attention Is All You Need," revolutionized the field of natural language processing. Unlike recurrent neural networks that process sequences sequentially, transformers process entire sequences in parallel, making them significantly more efficient and scalable. + +This post explores the fundamental concepts behind transformers and how they've evolved to power modern LLMs like GPT and BERT. + +## The Problem with RNNs + +Before transformers, RNNs and LSTMs were the standard approach for sequence modeling. However, they have several limitations: + +1. **Sequential Processing**: RNNs process sequences one token at a time, which prevents parallelization +2. **Long-Range Dependencies**: The vanishing gradient problem makes it difficult to capture dependencies far apart in sequences +3. **Memory Constraints**: Processing must maintain hidden states throughout the entire sequence + +## Self-Attention Mechanism + +The key innovation in transformers is the **self-attention mechanism**, which allows the model to weigh the importance of different tokens in a sequence. + +### Mathematical Formulation + +The attention mechanism is computed as: + +$$\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$ + +Where: +- **Q** (Query): Linear transformation of input +- **K** (Key): Linear transformation of input +- **V** (Value): Linear transformation of input +- **$d_k$**: Dimension of keys (used for scaling) + +### How It Works + +1. For each token (query), compute similarity scores with all tokens (keys) +2. Normalize scores using softmax +3. Compute weighted sum of values based on these scores + +This allows the model to dynamically decide which parts of the sequence are relevant for each position. + +## Multi-Head Attention + +Rather than using a single attention mechanism, transformers use multiple "heads" that attend to different parts of the sequence simultaneously. This allows the model to capture diverse relationships. + +$$\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, ..., \text{head}_h)W^O$$ + +Where each head computes attention on a different subspace of the representation. + +## The Transformer Architecture + +The full transformer consists of: + +1. **Encoder Stack**: Processes input sequences + - Multi-head attention layer + - Feed-forward networks + - Layer normalization and residual connections + +2. **Decoder Stack**: Generates output sequences + - Masked multi-head attention (prevents looking ahead) + - Cross-attention (attends to encoder output) + - Feed-forward networks + +3. **Positional Encoding**: Since transformers don't process sequences sequentially, positional information must be explicitly added + +## Evolution to Large Language Models + +Modern LLMs like GPT-3, ChatGPT, and others are essentially decoder-only transformer models scaled to billions of parameters, trained on massive amounts of text data using next-token prediction. + +### Key Improvements + +- **Scaling Laws**: Larger models with more data consistently improve performance +- **Instruction Tuning**: Fine-tuning on diverse tasks improves generalization +- **In-Context Learning**: Large models can learn from examples in the prompt +- **Chain-of-Thought**: Models can solve complex problems by reasoning step-by-step + +## Conclusion + +The transformer architecture's combination of parallelizable computation, effective long-range dependency modeling, and scalability has made it the foundation of modern NLP. Understanding these fundamentals is essential for anyone working with deep learning and AI today. + +The continued success of transformers in various domains (vision, multimodal, etc.) suggests they're likely to remain the dominant architecture for years to come. diff --git a/_posts/2025-02-03-distributed-training-guide.md b/_posts/2025-02-03-distributed-training-guide.md new file mode 100644 index 00000000000..8b5bb967c7d --- /dev/null +++ b/_posts/2025-02-03-distributed-training-guide.md @@ -0,0 +1,197 @@ +--- +layout: post +title: "Distributed Training Guide: Scaling Machine Learning Across Multiple GPUs" +date: 2025-02-03 +tags: [Distributed Computing, Deep Learning, Training, PyTorch, Performance] +excerpt: "Learn how to efficiently scale your ML models across multiple GPUs and machines using data parallelism, model parallelism, and distributed training frameworks." +--- + +## Introduction + +As machine learning models grow larger, training becomes computationally expensive. Distributed training allows us to leverage multiple GPUs and machines to reduce training time significantly. This guide covers practical approaches to scaling your models. + +## Why Distributed Training? + +Modern models like GPT-3 (175B parameters) or PaLM (540B parameters) cannot fit on a single GPU. Even smaller models that technically fit often train faster when distributed due to parallelization. + +**Benefits:** +- Reduced training time through parallelization +- Ability to train larger models +- Better hardware utilization +- Fault tolerance in large-scale operations + +## Data Parallelism + +The most common approach for distributed training is **data parallelism**, where the model is replicated across multiple devices, and training data is split among them. + +### How It Works + +``` +Device 1: Model + Batch 1 +Device 2: Model + Batch 2 +Device 3: Model + Batch 3 +Device 4: Model + Batch 4 +``` + +Each device: +1. Processes its data batch +2. Computes local gradients +3. Synchronizes gradients across all devices +4. Updates model parameters + +### PyTorch Implementation + +```python +import torch.distributed as dist +from torch.nn.parallel import DistributedDataParallel as DDP + +# Initialize distributed training +dist.init_process_group(backend="nccl") + +# Wrap model with DDP +model = Model(...) +model = DDP(model) + +# Train as usual +for epoch in range(num_epochs): + for batch in dataloader: + outputs = model(batch) + loss = criterion(outputs, labels) + loss.backward() + optimizer.step() +``` + +## Model Parallelism + +For extremely large models that don't fit on a single GPU, **model parallelism** splits the model across devices. + +### Strategies + +1. **Pipeline Parallelism**: Different layers on different devices + - Device 1: Layers 1-10 + - Device 2: Layers 11-20 + - Device 3: Layers 21-30 + +2. **Tensor Parallelism**: Split tensors across devices + - Useful for attention heads and feed-forward layers + - Requires more communication overhead + +### Trade-offs + +| Approach | Memory | Communication | Ease | +|----------|--------|---------------|------| +| Data Parallelism | High | Low | Easy | +| Pipeline Parallelism | Low | Medium | Medium | +| Tensor Parallelism | Low | High | Hard | + +## Advanced Techniques + +### Gradient Accumulation + +Simulate larger batch sizes without needing proportional memory: + +```python +accumulation_steps = 4 +for i, batch in enumerate(dataloader): + outputs = model(batch) + loss = criterion(outputs, labels) + loss.backward() + + if (i + 1) % accumulation_steps == 0: + optimizer.step() + optimizer.zero_grad() +``` + +### Mixed Precision Training + +Use lower precision (float16) for computation while keeping float32 for stability: + +```python +from torch.cuda.amp import autocast, GradScaler + +scaler = GradScaler() + +for batch in dataloader: + with autocast(): + outputs = model(batch) + loss = criterion(outputs, labels) + + scaler.scale(loss).backward() + scaler.step(optimizer) + scaler.update() +``` + +### Gradient Checkpointing + +Trade computation for memory by recomputing activations during backprop: + +```python +import torch.utils.checkpoint as checkpoint + +class Model(nn.Module): + def forward(self, x): + return checkpoint.checkpoint(self.layer1, x) +``` + +## Distributed Training Frameworks + +### DeepSpeed (Microsoft) + +Optimized for large-scale training with automatic mixed precision and gradient accumulation: + +```bash +pip install deepspeed +deepspeed train.py --deepspeed_config ds_config.json +``` + +### Hugging Face Accelerate + +Simplifies distributed training with minimal code changes: + +```python +from accelerate import Accelerator + +accelerator = Accelerator() +model, optimizer, train_dataloader = accelerator.prepare( + model, optimizer, train_dataloader +) + +for batch in train_dataloader: + outputs = model(batch) + loss = criterion(outputs, labels) + accelerator.backward(loss) + optimizer.step() +``` + +### PyTorch Lightning + +High-level abstraction for distributed training: + +```python +from pytorch_lightning import Trainer + +trainer = Trainer(strategy="ddp", gpus=4) +trainer.fit(model, train_dataloader) +``` + +## Performance Optimization Tips + +1. **Batch Size**: Larger batches improve GPU utilization but require more memory +2. **Learning Rate**: Often needs to scale with batch size +3. **Communication Overlapping**: Overlap gradient computation with communication +4. **Reduced Precision**: Use float16 when possible for 2-3x speedup +5. **Profiling**: Identify bottlenecks (compute vs. communication vs. I/O) + +## Scaling Laws + +Empirical studies show consistent scaling laws: + +- **Compute Optimal Scaling**: To reach a target loss, there's an optimal model size and dataset size +- **Chinchilla Scaling**: Optimal training uses roughly equal tokens and parameters (e.g., 70B model trained on 1.4T tokens) +- **Power Laws**: Loss decreases roughly as 1/N where N is compute + +## Conclusion + +Distributed training is essential for modern deep learning. Starting with data parallelism for most applications, then exploring model parallelism or advanced techniques for larger scales. The ecosystem of tools like DeepSpeed and Hugging Face Accelerate makes it more accessible than ever. + +The key is understanding your constraints—memory, communication, and time—and choosing the approach that best fits your hardware and model. diff --git a/_posts/2025-02-20-question-answering-systems.md b/_posts/2025-02-20-question-answering-systems.md new file mode 100644 index 00000000000..9d4fec0cf17 --- /dev/null +++ b/_posts/2025-02-20-question-answering-systems.md @@ -0,0 +1,289 @@ +--- +layout: post +title: "Building Effective Question Answering Systems with Transformers" +date: 2025-02-20 +tags: [NLP, Question Answering, Transformers, BERT, Information Retrieval] +excerpt: "Explore the architecture and training techniques for building robust question answering systems, from extractive to generative approaches." +--- + +## Introduction + +Question Answering (QA) systems are among the most practical NLP applications, with use cases ranging from customer service chatbots to research paper search engines. This post covers the spectrum of QA approaches, from simple extractive methods to sophisticated generative models. + +## QA System Architectures + +### 1. Extractive Question Answering + +Extractive QA finds answers by identifying relevant spans in provided context documents. + +**Characteristics:** +- Answer must exist in the context +- Generally faster inference +- Easier to explain/verify + +**Example:** +``` +Context: "Albert Einstein was born in Germany in 1879." +Question: "Where was Einstein born?" +Answer: "Germany" +``` + +### 2. Generative Question Answering + +Generative QA synthesizes answers from knowledge, not restricted to input text. + +**Characteristics:** +- Can answer open-ended questions +- Requires larger models +- Answers are generated token-by-token + +**Example:** +``` +Question: "Why is the sky blue?" +Answer: "The sky appears blue because of Rayleigh scattering..." +``` + +### 3. Hybrid Approaches + +Combine retrieval and generation: +1. Retrieve relevant documents +2. Generate answer based on retrieved context + +## Extractive QA: BERT-based Approach + +### Model Architecture + +BERT-style extractive QA uses a pre-trained transformer encoder: + +``` +[CLS] question tokens [SEP] context tokens [SEP] + ↓ + BERT Encoder (12 layers) + ↓ + [Start Position, End Position] +``` + +### Training + +```python +from transformers import AutoModelForQuestionAnswering, AutoTokenizer +import torch + +model = AutoModelForQuestionAnswering.from_pretrained('bert-base-uncased') +tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased') + +# Prepare inputs +inputs = tokenizer(question, context, return_tensors="pt") + +# Forward pass +outputs = model(**inputs) +start_logits = outputs.start_logits # Scores for each token as answer start +end_logits = outputs.end_logits # Scores for each token as answer end + +# Inference: find argmax positions +start_idx = torch.argmax(start_logits) +end_idx = torch.argmax(end_logits) + +# Extract answer +answer = tokenizer.convert_tokens_to_string( + tokenizer.convert_ids_to_tokens(inputs['input_ids'][0][start_idx:end_idx+1]) +) +``` + +### SQuAD Dataset + +Stanford Question Answering Dataset (SQuAD) is the standard benchmark: +- 100K+ question-answer pairs +- Answers are spans in Wikipedia articles +- Multiple reference answers per question + +**Fine-tuning typically achieves:** +- EM (Exact Match): ~85-95% (exact match with reference) +- F1 Score: ~92-97% (overlap-based metric) + +## Generative QA: Seq2Seq Approach + +### Architecture + +``` +Question: "What is photosynthesis?" + ↓ +[Encoder] BERT/GPT encodes question + ↓ +[Decoder] Generates answer token-by-token + ↓ +Answer: "Photosynthesis is the process..." +``` + +### Implementation with Hugging Face + +```python +from transformers import AutoModelForSeq2SeqLM, AutoTokenizer + +# Use T5 or BART +model = AutoModelForSeq2SeqLM.from_pretrained('t5-base') +tokenizer = AutoTokenizer.from_pretrained('t5-base') + +# T5 uses task-specific prefixes +inputs = tokenizer( + "question: What is AI? context: Artificial intelligence...", + return_tensors="pt" +) + +# Generate answer +outputs = model.generate( + inputs['input_ids'], + max_length=100, + num_beams=4, # Beam search + early_stopping=True +) + +answer = tokenizer.decode(outputs[0]) +``` + +## Retrieval-Augmented Generation (RAG) + +For knowledge-intensive tasks, retrieve relevant documents first: + +``` +Question + ↓ +[Retriever] Find k relevant documents + ↓ +Document 1, Document 2, ..., Document k + ↓ +[Generator] Generate answer with retrieved context + ↓ +Answer +``` + +### Implementation + +```python +from transformers import RagRetriever, RagTokenForGeneration + +retriever = RagRetriever.from_pretrained('facebook/rag-sequence-nq') +model = RagTokenForGeneration.from_pretrained('facebook/rag-sequence-nq') + +# Retrieve and generate +inputs = tokenizer(question, return_tensors="pt") +generated = model.generate( + input_ids=inputs['input_ids'], + context_input_ids=None # Retriever finds context +) + +answer = tokenizer.batch_decode(generated)[0] +``` + +## Building a Custom QA System + +### Step 1: Data Collection + +```python +qa_data = [ + { + "question": "Who wrote 1984?", + "context": "George Orwell wrote 1984, a dystopian novel...", + "answer": "George Orwell", + "answer_start": 0 + }, + # ... more examples +] +``` + +### Step 2: Preprocessing + +```python +def preprocess(examples): + questions = [q.strip() for q in examples['question']] + contexts = [c.strip() for c in examples['context']] + + inputs = tokenizer( + questions, + contexts, + max_length=384, + truncation="only_second", + return_offsets_mapping=True, + padding="max_length" + ) + + start_positions = [] + end_positions = [] + + for i, answer in enumerate(examples['answer']): + start_char = examples['answer_start'][i] + end_char = start_char + len(answer) + + # Map character positions to token positions + offsets = inputs['offset_mapping'][i] + start_token = next((j for j, (s, e) in enumerate(offsets) + if s <= start_char < e), 0) + end_token = next((j for j, (s, e) in enumerate(offsets) + if s < end_char <= e), len(offsets)-1) + + start_positions.append(start_token) + end_positions.append(end_token) + + inputs['start_positions'] = start_positions + inputs['end_positions'] = end_positions + return inputs +``` + +### Step 3: Fine-tuning + +```python +from transformers import Trainer, TrainingArguments + +training_args = TrainingArguments( + output_dir='./qa_model', + num_train_epochs=3, + per_device_train_batch_size=16, + per_device_eval_batch_size=16, + warmup_steps=500, + weight_decay=0.01, + logging_dir='./logs', +) + +trainer = Trainer( + model=model, + args=training_args, + train_dataset=train_dataset, + eval_dataset=eval_dataset, + callbacks=[EarlyStoppingCallback(early_stopping_patience=3)] +) + +trainer.train() +``` + +## Evaluation Metrics + +### Extractive QA + +- **Exact Match (EM)**: Percentage of predictions that match reference exactly +- **F1 Score**: Overlap between predicted and reference answer + +### Generative QA + +- **ROUGE**: Overlap of n-grams and longest common subsequence +- **BLEU**: Precision of n-grams in generated output +- **METEOR**: Similar to BLEU but accounts for synonyms + +## Challenges and Solutions + +| Challenge | Solution | +|-----------|----------| +| Out-of-domain questions | Transfer learning + domain adaptation | +| Long context | Hierarchical encoding, sparse attention | +| Multi-hop reasoning | Iterative retrieval, chain-of-thought prompting | +| Factual consistency | Retrieval-augmentation, fact verification | + +## Conclusion + +Question answering systems continue to advance with larger models and better training techniques. For production systems, consider: + +1. **Extractive QA** for closed-domain, fast inference needs +2. **Generative QA** for open-ended, knowledge-intensive tasks +3. **RAG** for knowledge-grounded systems +4. **Ensemble approaches** combining multiple methods for robustness + +The field is rapidly evolving, with new architectures and techniques emerging regularly. Staying updated with recent research and model releases is crucial for building state-of-the-art QA systems. diff --git a/_sass/_animations.scss b/_sass/_animations.scss index 25ef77fbbfc..2e727d194a1 100644 --- a/_sass/_animations.scss +++ b/_sass/_animations.scss @@ -5,17 +5,102 @@ @-webkit-keyframes intro { 0% { opacity: 0; + transform: translateY(10px); } 100% { opacity: 1; + transform: translateY(0); } } @keyframes intro { 0% { opacity: 0; + transform: translateY(10px); } 100% { opacity: 1; + transform: translateY(0); } -} \ No newline at end of file +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes slideInLeft { + from { + opacity: 0; + transform: translateX(-20px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes pulse { + 0%, 100% { + transform: scale(1); + } + 50% { + transform: scale(1.05); + } +} + +@keyframes shimmer { + 0% { + background-position: -200% 0; + } + 100% { + background-position: 200% 0; + } +} + +@keyframes gradientFlow { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +/* Animation utility classes */ +.animate-fade-in { + animation: fadeIn 0.6s ease-out forwards; +} + +.animate-fade-in-up { + animation: fadeInUp 0.6s ease-out forwards; +} + +.animate-slide-in-left { + animation: slideInLeft 0.6s ease-out forwards; +} + +/* Staggered animation delays */ +.delay-1 { animation-delay: 0.1s; } +.delay-2 { animation-delay: 0.2s; } +.delay-3 { animation-delay: 0.3s; } +.delay-4 { animation-delay: 0.4s; } +.delay-5 { animation-delay: 0.5s; } \ No newline at end of file diff --git a/_sass/_education.scss b/_sass/_education.scss new file mode 100644 index 00000000000..956bcb5200a --- /dev/null +++ b/_sass/_education.scss @@ -0,0 +1,132 @@ +/* ========================================================================== + EDUCATION & TRAINING (About page) + ========================================================================== */ + +.education-item { + position: relative; + padding: 1.2em 1.25em; + margin: 0.9em 0; + background: #ffffff; + border-radius: $border-radius-lg; + border: 1px solid $border-color; + border-left: 3px solid $primary-color; /* clean left accent */ + box-shadow: 0 10px 30px rgba(15, 23, 42, 0.04); + transition: transform 0.22s ease, box-shadow 0.22s ease, border-color 0.22s ease; + + &:hover { + transform: translateY(-2px); + box-shadow: 0 14px 40px rgba(15, 23, 42, 0.06); + border-color: #e9e9e9; + } + + .education-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 12px; + flex-wrap: wrap; + } + + .education-degree { + font-weight: 750; + color: $darker-gray; + font-size: 1.12em; + letter-spacing: -0.01em; + margin-bottom: 0.2em; + } + + .education-school { + color: $primary-color; + font-weight: 600; + font-size: 1em; + margin-bottom: 0.15em; + } + + .education-date { + color: $gray; + font-size: 0.92em; + font-weight: 400; + font-variant-numeric: tabular-nums; + } + + .education-meta { + text-align: right; + + @include breakpoint($small) { + min-width: 180px; + } + } + + /* GPA: subtle, minimalist */ + .education-gpa { + display: inline-block; + margin-top: 0.15em; + padding: 0; + background: transparent; + color: $dark-gray; + font-size: 0.92em; + font-weight: 500; + border-radius: 0; + } + + /* Coursework: scannable tags */ + .coursework { + margin-top: 0.9em; + } + + .coursework-title { + color: $gray; + font-size: 0.9em; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.06em; + margin-bottom: 0.5em; + } + + .coursework-tags { + display: flex; + flex-wrap: wrap; + gap: 0.5em; + } + + .course-tag { + display: inline-flex; + align-items: center; + padding: 0.28em 0.7em; + border-radius: 999px; + background: #f1f5f9; + border: 1px solid #e2e8f0; + color: $dark-gray; + font-size: 0.85em; + font-weight: 500; + line-height: 1; + + &:hover { + border-color: rgba($primary-color, 0.35); + color: $primary-color-dark; + background: rgba($primary-color, 0.06); + } + } + + &.education-item--compact { + padding: 1em 1.15em; + + .education-degree { + font-size: 1.02em; + font-weight: 700; + } + + .education-school { + font-weight: 600; + } + } + + &.training-item { + .training-desc { + margin-top: 0.75em; + color: $text-color-light; + font-size: 0.98em; + line-height: 1.65; + } + } +} diff --git a/_sass/_masthead.scss b/_sass/_masthead.scss index 90397f2c53b..dbba6454236 100644 --- a/_sass/_masthead.scss +++ b/_sass/_masthead.scss @@ -5,18 +5,20 @@ .masthead { position: sticky; top: 0; - background-color: white; + background-color: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); border-bottom: 1px solid $border-color; -webkit-animation: intro 0.3s both; animation: intro 0.3s both; -webkit-animation-delay: 0.15s; animation-delay: 0.15s; - z-index: 20; + z-index: 100; &__inner-wrap { @include container; @include clearfix; - padding: .5em; + padding: 0.75em 1em; font-family: $sans-serif-narrow; @include breakpoint($x-large) { @@ -29,6 +31,29 @@ a { text-decoration: none; + color: $dark-gray; + font-weight: 500; + position: relative; + padding: 0.5em 0; + + &::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + width: 0; + height: 2px; + background: linear-gradient(90deg, $primary-color, $primary-color-light); + transition: width 0.3s ease; + } + + &:hover { + color: $primary-color; + + &::after { + width: 100%; + } + } } } } @@ -58,6 +83,18 @@ &--lg { padding-right: 2em; font-weight: 700; + + a { + font-size: 1.1em; + background: linear-gradient(135deg, $primary-color, $primary-color-light); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + + &::after { + display: none; + } + } } } diff --git a/_sass/_page.scss b/_sass/_page.scss index 32c17f86bb0..fd223bb32c8 100644 --- a/_sass/_page.scss +++ b/_sass/_page.scss @@ -6,10 +6,19 @@ @include container; @include clearfix; margin-top: 1em; + margin-left: auto; + margin-right: auto; padding-left: 1em; padding-right: 1em; - animation: intro 0.3s both; - animation-delay: 0.35s; + animation: intro 0.5s both; + animation-delay: 0.2s; + max-width: 100%; + + @include breakpoint($large) { + display: flex; + gap: 2em; + align-items: flex-start; + } @include breakpoint($x-large) { max-width: $x-large; @@ -18,9 +27,8 @@ .page { @include breakpoint($large) { - @include span(10 of 12 last); - @include prefix(0.5 of 12); - @include suffix(0 of 12); + flex: 1; + min-width: 0; } .page__inner-wrap { @@ -49,30 +57,47 @@ } .page__content { - #about-me{ - margin-top: -10em; - &:before { - content: ''; - display: block; - position: relative; - width: 0; - height: 10em; - margin-top: -10em; + position: relative; + z-index: 1; + + #about-me { + margin-top: 0; + padding-top: 0; + &:before { + content: ''; + display: block; + position: relative; + width: 0; + height: 0; + margin-top: 0; } } + h1 { - margin-top: 1em; + margin-top: 2em; padding-bottom: 0.5em; - border-bottom: 1px solid $border-color; + border-bottom: none; + font-weight: 700; + color: $darker-gray; + } + + h2 { + margin-top: 2em; + margin-bottom: 1em; + font-size: $type-size-2; + font-weight: 700; + color: $darker-gray; } p, li, dl { font-size: 1em; + line-height: 1.7; + color: $text-color; } /* paragraph indents */ p { - margin: 0 0 $indent-var; + margin: 0 0 1em; /* sibling indentation*/ @if $paragraph-indent == true { @@ -84,13 +109,18 @@ } a { - text-decoration: underline; + text-decoration: none; + color: $link-color; + font-weight: 500; + border-bottom: 1px solid transparent; + transition: all 0.2s ease; &:hover { - text-decoration: underline; + color: $link-color-hover; + border-bottom-color: $link-color-hover; img { - box-shadow: 0 0 10px rgba(#000, 0.25); + box-shadow: 0 8px 25px rgba(#000, 0.15); } } } @@ -116,6 +146,73 @@ margin-top: -1.5em; padding-left: 1.25rem; } + + /* Strong text styling */ + strong { + font-weight: 600; + color: $darker-gray; + } + + /* Emphasis/italics */ + em { + color: $gray; + } + + /* Academic timeline (News) */ + .news-timeline { + margin: 0.75em 0 0; + padding: 0; + list-style: none; + + .news-item { + display: flex; + align-items: baseline; + gap: 0.75rem; + margin: 0 0 18px; + padding: 0; + border-radius: 0; + background: transparent; + border: 0; + + .news-date { + display: inline-block; + min-width: 5.2em; /* aligns YYYY.MM */ + font-weight: 400; + font-size: 0.92em; + color: $gray; + font-variant-numeric: tabular-nums; + letter-spacing: 0.2px; + } + + .news-text { + flex: 1; + color: $darker-gray; + font-weight: 400; + transition: color 0.18s ease; + + &:hover { + color: $link-color; + } + } + + /* Major achievements */ + &.highlight { + .news-text { + font-weight: 600; + } + } + + /* tight, consistent spacing between emoji and text */ + .news-emoji { + margin-right: 0.4rem; + } + + /* if emoji is inside an icon wrapper */ + .news-text > span[aria-hidden="true"] { + margin-right: 0.4rem; + } + } + } } .page__hero { @@ -410,3 +507,34 @@ font-size: $type-size-6; text-transform: uppercase; } + +/* ========================================================================== + News Section + ========================================================================== */ + +h1, h2, h3, h4, h5, h6 { + clear: both; + position: relative; + z-index: 2; + margin-top: 1.5em; + margin-bottom: 0.75em; + padding-top: 0.5em; + } + + section { + position: relative; + z-index: 1; + margin-bottom: 2em; + + &:first-of-type { + margin-top: 1em; + } + } + + /* News list specific styling */ + > ul:not(.social-icons) { + clear: both; + margin-top: 1.5em; + margin-bottom: 2em; + padding-top: 1em; + } diff --git a/_sass/_posts.scss b/_sass/_posts.scss new file mode 100644 index 00000000000..14b7ddcd64c --- /dev/null +++ b/_sass/_posts.scss @@ -0,0 +1,931 @@ +/* ========================================================================== + BLOG POSTS STYLING + ========================================================================== */ + +/* Blog Index Page */ + +.blog__header { + margin-bottom: 3em; + text-align: left; + padding: 0 0 2em 0; + border-bottom: 2px solid $border-color; + + animation: slideDown 0.6s ease-out; +} + +.blog__title { + font-size: $type-size-1; + font-weight: 700; + color: $darker-gray; + margin-bottom: 0.5em; + text-align: left; +} + +.blog__subtitle { + font-size: $type-size-4; + color: $text-color-light; + max-width: 100%; + margin: 0; + text-align: left; +} + +.blog__medium-link { + display: inline-block; + color: $primary-color; + text-decoration: none; + font-weight: 600; + font-size: $type-size-5; + margin-top: 1.5em; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + font-family: $sans-serif; + letter-spacing: 0.02em; + position: relative; + + &::after { + content: ""; + position: absolute; + bottom: -2px; + left: 0; + width: 0; + height: 2px; + background: $primary-color; + transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1); + } + + &:hover { + color: $primary-color-dark; + text-decoration: none; + + &::after { + width: 100%; + } + } + + &:active { + transform: translateY(1px); + } +} + +/* Search and Filter Controls */ + +.blog__controls { + margin-bottom: 3.5em; + display: flex; + flex-direction: column; + gap: 2em; + + @include breakpoint($small) { + flex-direction: row; + align-items: center; + justify-content: space-between; + gap: 1.5em; + } +} + +.blog__search-input { + flex: 1; + padding: 0.875em 1.25em; + font-size: $type-size-5; + border: 1px solid $border-color; + border-radius: 8px; + background-color: $body-color; + color: $text-color; + transition: all 0.3s ease; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); + + &:focus { + outline: none; + border-color: $primary-color; + box-shadow: 0 4px 12px rgba($primary-color, 0.12); + } + + &::placeholder { + color: $light-gray; + } + + @include breakpoint($small) { + max-width: 400px; + } +} + +.blog__tag-filter { + display: flex; + flex-wrap: wrap; + gap: 0.75em; + align-items: center; + margin-bottom: 0.5em; + + @include breakpoint($small) { + justify-content: flex-end; + margin-bottom: 0; + } +} + +.blog__filter-btn { + padding: 0.6em 1.2em; + border: 1px solid $border-color; + border-radius: 20px; + background-color: transparent; + color: $text-color; + font-size: $type-size-6; + font-weight: 500; + cursor: pointer; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + white-space: nowrap; + + &:hover { + border-color: $primary-color; + color: $primary-color; + background-color: rgba($primary-color, 0.05); + } + + &.active { + background-color: $primary-color; + border-color: $primary-color; + color: white; + box-shadow: 0 4px 12px rgba($primary-color, 0.3); + } +} + +/* Blog Posts Container */ + +.blog__container { + animation: fadeIn 0.6s ease-out; +} + +.blog__posts { + display: grid; + grid-template-columns: 1fr; + gap: 2em; + + @include breakpoint($small) { + grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); + } + + @include breakpoint($medium) { + grid-template-columns: repeat(2, 1fr); + } + + @include breakpoint($large) { + grid-template-columns: repeat(2, 1fr); + } +} + +/* Blog Post Card */ + +.blog__post-card { + display: flex; + flex-direction: column; + padding: 1.75em; + background-color: $body-color; + border: 1px solid $border-color; + border-radius: 12px; + transition: all 0.3s ease; + animation: slideUp 0.5s ease-out both; + min-height: 380px; + + @for $i from 1 through 10 { + &:nth-child(#{$i}) { + animation-delay: #{$i * 0.05}s; + } + } + + &:hover { + border-color: $primary-color; + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1); + transform: translateY(-4px); + } +} + +.blog__post-header { + margin-bottom: 1em; +} + +.blog__post-title { + margin: 0 0 0.5em; + font-size: $type-size-4; + font-weight: 700; + line-height: 1.3; + color: $darker-gray; + + a { + color: inherit; + text-decoration: none; + transition: color 0.3s ease; + + &:hover { + color: $primary-color; + } + } +} + +.blog__post-meta { + display: flex; + flex-wrap: wrap; + gap: 1em; + margin-bottom: 1em; + font-size: $type-size-6; + color: $text-color-light; + + i { + margin-right: 0.3em; + } +} + +.blog__post-date, +.blog__post-reading-time { + display: flex; + align-items: center; +} + +.blog__post-excerpt { + font-size: $type-size-5; + color: $text-color; + line-height: 1.6; + margin-bottom: 1em; + flex-grow: 1; +} + +/* Post Tags (Card View) */ + +.blog__post-tags { + display: flex; + flex-wrap: wrap; + gap: 0.75em; + margin-bottom: 1.5em; + margin-top: auto; +} + +.blog__post-tag { + display: inline-block; + padding: 0.4em 1em; + background-color: rgba($primary-color, 0.08); + color: $primary-color; + border: 1px solid rgba($primary-color, 0.2); + border-radius: 20px; + font-size: $type-size-7; + font-weight: 500; + transition: all 0.3s ease; + cursor: default; + + &:hover { + background-color: rgba($primary-color, 0.15); + border-color: rgba($primary-color, 0.4); + } +} + +.blog__post-link { + display: inline-flex; + align-items: center; + gap: 0.5em; + color: $primary-color; + font-weight: 600; + text-decoration: none; + transition: all 0.3s ease; + margin-top: auto; + + &:hover { + gap: 0.8em; + color: $primary-color-dark; + } + + i { + transition: transform 0.3s ease; + } + + &:hover i { + transform: translateX(4px); + } +} + +/* Empty State */ + +.blog__empty-state { + grid-column: 1 / -1; + text-align: center; + padding: 3em 2em; + + i { + font-size: 3em; + color: $light-gray; + margin-bottom: 1em; + } + + h2 { + color: $darker-gray; + margin-bottom: 0.5em; + } + + p { + color: $text-color-light; + } +} + +/* ========================================================================== + SINGLE POST PAGE + ========================================================================== */ + +.post { + @include clearfix; +} + +/* Unified wrapper for aligned header and content */ +.post__wrapper { + max-width: 750px; + margin: 0 auto; + padding: 0 1.5em; +} + +.post__header { + margin-bottom: 3.5em; + padding-bottom: 2.5em; + border-bottom: 2px solid $border-color; +} + +.post__title { + font-size: $type-size-1; + font-weight: 700; + color: $darker-gray; + line-height: 1.2; + margin: 0 0 1.5em; +} + +.post__meta { + display: flex; + flex-wrap: wrap; + gap: 2em; + margin-bottom: 2.5em; + padding-bottom: 2em; + font-size: $type-size-6; + color: $text-color-light; + + i { + margin-right: 0.5em; + color: $primary-color; + } +} + +.post__date, +.post__reading-time, +.post__author { + display: flex; + align-items: center; + gap: 0.3em; +} + +.post__excerpt { + font-size: $type-size-4; + color: $text-color; + line-height: 1.7; + font-style: italic; + border-left: 4px solid $primary-color; + padding-left: 1.5em; + margin-bottom: 1.5em; +} + +/* Post Tags (Header) */ + +.post__tags { + display: flex; + flex-wrap: wrap; + gap: 0.6em; + margin-bottom: 1.2em; +} + +.post__tag { + display: inline-block; + padding: 0.5em 0.95em; + background-color: rgba($primary-color, 0.08); + color: $primary-color; + border-radius: 6px; + font-size: $type-size-6; + font-weight: 500; + text-decoration: none; + transition: all 0.3s ease; + border: 1px solid rgba($primary-color, 0.3); + + &:hover { + background-color: $primary-color; + color: white; + border-color: $primary-color; + } +} + +/* Post Content Container */ + +.post__container { + display: block; + margin-bottom: 3em; +} + +/* Table of Contents */ +/* Removed - ToC feature disabled for cleaner layout */ + +/* Post Content Typography */ + +.post__content { + font-size: $type-size-5; + line-height: 1.75; + color: $text-color; + + h1, + h2, + h3, + h4, + h5, + h6 { + margin-top: 2.2em; + margin-bottom: 1.2em; + color: $darker-gray; + font-weight: 700; + line-height: 1.3; + } + + h1 { + font-size: $type-size-2; + } + + h2 { + font-size: $type-size-2; + font-weight: 900; + padding-bottom: 1em; + border-bottom: 2px solid $border-color; + margin-top: 2.5em; + margin-bottom: 1.8em; + } + + h3 { + font-size: $type-size-3; + font-weight: 800; + margin-top: 2em; + margin-bottom: 1.2em; + color: darken($darker-gray, 5%); + } + + h4, + h5, + h6 { + font-size: $type-size-4; + font-weight: 700; + margin-top: 1.8em; + margin-bottom: 1em; + } + + /* Increase spacing for headers followed by code blocks */ + h1 + pre, + h2 + pre, + h3 + pre, + h4 + pre, + h5 + pre, + h6 + pre { + margin-top: 1.5em; + } + + h2 + pre { + margin-top: 2em; + } + + h3 + pre { + margin-top: 1.8em; + } + + p { + margin-bottom: 1.5em; + } + + a { + color: $primary-color; + text-decoration: none; + border-bottom: 1px solid $primary-color; + transition: all 0.3s ease; + + &:hover { + color: $primary-color-dark; + border-bottom-color: $primary-color-dark; + } + } + + strong { + font-weight: 700; + color: $darker-gray; + } + + em { + font-style: italic; + } + + ul, + ol { + margin-bottom: 1.8em; + margin-top: 1em; + padding-left: 2.5em; + + li { + margin-bottom: 1em; + line-height: 1.8; + } + } + + ol { + list-style: decimal; + } + + ul { + list-style: disc; + + ul { + list-style: circle; + padding-left: 1.8em; + margin-top: 0.6em; + margin-bottom: 0.6em; + } + } + + blockquote { + margin: 2em 0; + padding: 1.5em 1.5em; + border-left: 4px solid $primary-color; + background-color: rgba($primary-color, 0.04); + font-style: italic; + color: $text-color-light; + + p { + margin-bottom: 0; + } + } + + code { + padding: 0.25em 0.5em; + font-family: 'JetBrains Mono', 'Fira Code', $monospace; + font-size: 0.85em; + background-color: $code-background-color; + border-radius: 4px; + color: #d63384; + letter-spacing: -0.01em; + } + + /* Code block styling (pre) is now handled globally in _syntax.scss */ + + table { + width: 100%; + margin-bottom: 2em; + margin-top: 1em; + border-collapse: collapse; + + thead { + background-color: $code-background-color; + } + + th, + td { + padding: 0.875em; + text-align: left; + border-bottom: 1px solid $border-color; + } + + th { + font-weight: 700; + color: $darker-gray; + } + + tbody tr:hover { + background-color: rgba($primary-color, 0.03); + } + } + + img { + max-width: 100%; + height: auto; + margin: 2em 0; + border-radius: 12px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12); + } + + hr { + margin: 3em 0; + border: none; + border-top: 2px solid $border-color; + } +} + +/* Post Tags (Footer) */ + +.post__tags-footer { + margin: 0 auto 3em; + max-width: 750px; + padding: 0 1.5em; + + h4 { + margin: 0 0 1.2em; + color: $darker-gray; + font-size: $type-size-6; + text-transform: uppercase; + letter-spacing: 0.05em; + font-weight: 700; + } +} + +.post__tag-badge { + display: inline-block; + margin-right: 0.8em; + margin-bottom: 0.6em; + padding: 0.6em 1em; + background-color: rgba($primary-color, 0.08); + color: white; + border-radius: 6px; + text-decoration: none; + font-size: $type-size-6; + font-weight: 500; + transition: all 0.3s ease; + border: 1px solid rgba($primary-color, 0.3); + + &:hover { + background-color: $primary-color; + border-color: $primary-color; + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba($primary-color, 0.25); + } +} + +/* Post Navigation */ + +.post__footer { + margin-bottom: 3em; + padding-bottom: 2em; + border-bottom: 1px solid $border-color; +} + +.post__navigation { + margin: 0 auto 3.5em; + max-width: 750px; + padding: 0 1.5em; + display: flex; + justify-content: space-between; + align-items: center; + gap: 2em; + flex-wrap: wrap; +} + +.post__nav-item { + flex: 1; + min-width: 200px; + text-align: center; + + @include breakpoint($small) { + min-width: auto; + } +} + +.post__nav-prev { + text-align: left; + + @include breakpoint($small) { + flex: 0 1 auto; + text-align: left; + } +} + +.post__nav-next { + text-align: right; + + @include breakpoint($small) { + flex: 0 1 auto; + text-align: right; + } +} + +.post__nav-link { + display: inline-block; + color: $primary-color; + text-decoration: none; + transition: all 0.3s ease; + font-weight: 500; + font-size: $type-size-5; + + &:hover { + .post__nav-label { + color: $primary-color; + text-decoration: underline; + } + + .post__nav-title { + color: $primary-color; + text-decoration: underline; + } + } +} + +.post__nav-label { + display: block; + font-size: $type-size-7; + color: $text-color-light; + margin-bottom: 0.3em; + font-weight: 500; + transition: all 0.3s ease; +} + +.post__nav-label--disabled { + display: inline-block; + font-size: $type-size-6; + color: $light-gray; + font-weight: 500; + cursor: not-allowed; +} + +.post__nav-title { + display: block; + font-size: $type-size-5; + color: $darker-gray; + font-weight: 600; + line-height: 1.4; + transition: all 0.3s ease; + + .post__nav-link:hover & { + color: $primary-color; + } +} + +/* Author Section */ + +.post__author-section { + margin: 0 auto 3em; + max-width: 750px; + padding: 2em 1.5em; + background-color: rgba($primary-color, 0.04); + border-radius: 8px; + border-left: none; +} + +.post__author-box { + text-align: center; + + h3 { + font-size: $type-size-7; + color: $text-color-light; + text-transform: uppercase; + letter-spacing: 0.08em; + margin-bottom: 1.2em; + font-weight: 600; + } + + h4 { + font-size: $type-size-3; + color: $darker-gray; + margin-bottom: 0.8em; + font-weight: 700; + } +} + +.post__author-avatar { + width: 100px; + height: 100px; + border-radius: 50%; + margin: 0 auto 1.2em; + border: 3px solid $primary-color; + object-fit: cover; +} + +.post__author-box p { + font-size: $type-size-5; + color: $text-color; + line-height: 1.6; + margin-bottom: 0.8em; +} + +.post__author-location { + color: $text-color-light; + font-size: $type-size-6; + margin-bottom: 1.2em !important; + + i { + margin-right: 0.4em; + color: $primary-color; + } +} + +.post__author-links { + display: flex; + justify-content: center; + gap: 1em; +} + +.post__author-link { + display: inline-flex; + align-items: center; + justify-content: center; + width: 38px; + height: 38px; + border-radius: 50%; + background-color: white; + color: $primary-color; + text-decoration: none; + font-size: $type-size-5; + transition: all 0.3s ease; + border: 1px solid $border-color; + + &:hover { + background-color: $primary-color; + color: white; + transform: translateY(-3px); + box-shadow: 0 4px 12px rgba($primary-color, 0.3); + } +} + +/* Back to Blog Link */ + +.post__back-link { + margin: 0 auto; + max-width: 750px; + padding: 2em 1.5em 0; + border-top: 1px solid $border-color; + + .btn { + display: inline-flex; + align-items: center; + gap: 0.5em; + } +} + +/* Animations */ + +@keyframes slideUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes slideDown { + from { + opacity: 0; + transform: translateY(-20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@include breakpoint($small) { + .blog__posts { + gap: 1.5em; + } + + .post__wrapper { + padding: 0 1em; + } + + .post__navigation { + gap: 1em; + } +} + +@include breakpoint($small) { + .blog__title { + font-size: $type-size-2; + } + + .post__title { + font-size: $type-size-2; + } + + .blog__post-card { + padding: 1em; + } + + .post__meta { + gap: 1em; + font-size: $type-size-7; + } + + .post__navigation { + grid-template-columns: 1fr; + gap: 1.5em; + } + + .post__nav-next { + text-align: left; + } + + .blog__controls { + flex-direction: column; + } + + .blog__tag-filter { + width: 100%; + justify-content: flex-start; + } +} diff --git a/_sass/_projects.scss b/_sass/_projects.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/_sass/_sidebar.scss b/_sass/_sidebar.scss index 2b635af6232..a9e40f1b308 100644 --- a/_sass/_sidebar.scss +++ b/_sass/_sidebar.scss @@ -12,9 +12,12 @@ @include clearfix(); margin-bottom: 1em; + width: 100%; @include breakpoint($large) { - @include span(2 of 12); + width: 280px; + flex-shrink: 0; + margin-bottom: 0; opacity: 1; -webkit-transition: opacity 0.2s ease-in-out; transition: opacity 0.2s ease-in-out; @@ -24,8 +27,8 @@ } } - @include breakpoint($x-large) { + width: 300px; padding-right: 0; } @@ -41,7 +44,7 @@ p, li { font-family: $sans-serif; font-size: $type-size-6; - line-height: 1.5; + line-height: 1.6; } img { @@ -69,62 +72,89 @@ Author profile and links ========================================================================== */ .profile_box{ - @include breakpoint($large) { - display: block; - } display: flex; + flex-wrap: wrap; justify-content: flex-start; align-content: flex-start; - align-items: center; + align-items: flex-start; + gap: 1em; + width: 100%; + + @include breakpoint($large) { + display: flex; + flex-direction: column; + text-align: left; + justify-content: flex-start; + align-items: flex-start; + gap: 0; + } } .author__avatar { - display: table-cell; - vertical-align: top; - width: 75px; - // set width only, for non-square avatars - // height: 36px; + display: block; + width: 80px; + margin: 0; @include breakpoint($large) { display: block; width: auto; height: auto; + margin: 0; + margin-bottom: 1em; } img { max-width: 175px; min-width: 75px; border-radius: 50%; + object-fit: cover; + aspect-ratio: 1 / 1; + box-shadow: 0 8px 30px rgba(37, 99, 235, 0.15); + transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.4s cubic-bezier(0.4, 0, 0.2, 1); @include breakpoint($large) { padding: 5px; - border: 1px solid $border-color; + border: 3px solid transparent; + background: linear-gradient(white, white) padding-box, + linear-gradient(135deg, $primary-color, #7c3aed) border-box; + max-width: 100%; + width: 100%; + } + + &:hover { + transform: scale(1.05) rotate(2deg); + box-shadow: 0 12px 40px rgba(37, 99, 235, 0.25); } } } .author__content { - display: table-cell; - vertical-align: top; - padding-left: 10px; - min-width: 120px; - // padding-right: 25px; - line-height: 1; + display: block; + padding-left: 0; + min-width: auto; + line-height: 1.3; + width: 100%; + flex: 1; @include breakpoint($large) { display: block; width: 100%; padding-left: 0; padding-right: 0; + flex: none; } } .author__name { margin: 0; + font-weight: 700; + color: $darker-gray; + text-align: left; @include breakpoint($large) { - margin-top: 10px; - margin-bottom: 10px; + margin-top: 0; + margin-bottom: 8px; + text-align: left; } } @@ -138,10 +168,21 @@ .author__bio { margin: 0; + color: $text-color-light; + font-size: $type-size-6; + line-height: 1.6; + letter-spacing: 0.01em; + text-align: left; @include breakpoint($large) { - margin-top: 10px; + margin-top: 15px; margin-bottom: 20px; + padding: 0.8em 1em; + background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); + border-radius: 8px; + border-left: 3px solid $primary-color; + text-align: left; + font-size: $type-size-6; } } @@ -151,9 +192,9 @@ vertical-align: middle; font-family: $sans-serif; z-index: 10; - position: relative; - margin-left: auto; cursor: pointer; + width: auto; + margin-left: 0; li:last-child { a { @@ -163,6 +204,9 @@ @include breakpoint($large) { display: block; + position: relative; + margin-left: 0; + margin-top: 1em; } button { @@ -180,13 +224,13 @@ position: absolute; right: 0; margin-top: 15px; - padding: 10px; + padding: 15px; list-style-type: none; border: 1px solid $border-color; - border-radius: $border-radius; + border-radius: $border-radius-lg; background: #fff; z-index: -1; - box-shadow: 0 0 10px rgba(#000, 0.25); + box-shadow: $box-shadow-lg; cursor: default; @include breakpoint($large) { @@ -267,4 +311,37 @@ @include breakpoint($large) { display: none; } +} + +/* ========================================================================== + STICKY SIDEBAR + ========================================================================== */ + +.sidebar.sticky { + position: sticky; + top: 2em; + max-height: calc(100vh - 2em); + overflow-y: auto; + + @include breakpoint($large) { + top: 2em; + } +} + +/* Ensure no overflow on sidebar */ +.sidebar.sticky::-webkit-scrollbar { + width: 6px; +} + +.sidebar.sticky::-webkit-scrollbar-track { + background: transparent; +} + +.sidebar.sticky::-webkit-scrollbar-thumb { + background: $border-color; + border-radius: 3px; + + &:hover { + background: $light-gray; + } } \ No newline at end of file diff --git a/_sass/_syntax.scss b/_sass/_syntax.scss index f40ed050b0b..605a19bfc63 100644 --- a/_sass/_syntax.scss +++ b/_sass/_syntax.scss @@ -1,123 +1,164 @@ /* ========================================================================== - Syntax highlighting + Syntax highlighting (One Dark theme) ========================================================================== */ div.highlighter-rouge, figure.highlight { position: relative; - margin-bottom: 1em; - padding: 1em; - border: 1px solid $border-color; - border-radius: $border-radius; - background-color: $code-background-color; - box-shadow: $box-shadow; + margin-bottom: 2em; + background-color: #282c34 !important; + color: #abb2bf; + border-radius: 8px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + overflow: hidden; - &:before { + /* Mac-like dots */ + &::before { + content: ''; + display: block; + height: 12px; + width: 12px; + border-radius: 50%; + background-color: #ff5f56; position: absolute; - top: 0; - right: 0; - padding: 0.5em; - background-color: $lighter-gray; - content: "\f121"; - font-family: "fontawesome" !important; - font-size: $type-size-6; - line-height: 1; - text-transform: none; - speak: none; + top: 14px; + left: 14px; + box-shadow: 20px 0 0 #ffbd2e, 40px 0 0 #27c93f; + z-index: 1; } .highlight { margin: 0; - font-family: $monospace; - font-size: $type-size-7; - line-height: 1.8; + font-family: "JetBrains Mono", "Fira Code", monospace; + font-size: 15px; /* Better readability */ + line-height: 1.6; + padding-top: 36px; /* Space for the mac dots */ + background-color: transparent !important; + } + + pre { + margin: 0; + padding: 0 16px 16px 16px; + overflow-x: auto; + background: transparent !important; + border: none; + box-shadow: none; + border-radius: 0; + padding-top: 0; + + code { + padding: 0; + background: none !important; + color: inherit; + border: none; + font-size: 1em; + font-family: inherit; + } } } .highlight table td { padding: 5px; } .highlight table pre { margin: 0; } +/* One Dark syntax highlighting colors */ +.highlight .c { color: #5c6370; font-style: italic } /* Comment */ +.highlight .err { color: #e06c75 } /* Error */ +.highlight .g { color: #abb2bf } /* Generic */ +.highlight .k { color: #c678dd } /* Keyword */ +.highlight .l { color: #abb2bf } /* Literal */ +.highlight .n { color: #abb2bf } /* Name */ +.highlight .o { color: #56b6c2 } /* Operator */ +.highlight .x { color: #abb2bf } /* Other */ +.highlight .p { color: #abb2bf } /* Punctuation */ +.highlight .cm { color: #5c6370; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #e5c07b } /* Comment.Preproc */ +.highlight .c1 { color: #5c6370; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #5c6370; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #e06c75 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #e06c75 } /* Generic.Error */ +.highlight .gh { color: #e5c07b; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #98c379 } /* Generic.Inserted */ +.highlight .go { color: #5c6370 } /* Generic.Output */ +.highlight .gp { color: #abb2bf } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #56b6c2; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #e06c75 } /* Generic.Traceback */ +.highlight .kc { color: #d19a66 } /* Keyword.Constant */ +.highlight .kd { color: #c678dd } /* Keyword.Declaration */ +.highlight .kn { color: #c678dd } /* Keyword.Namespace */ +.highlight .kp { color: #c678dd } /* Keyword.Pseudo */ +.highlight .kr { color: #c678dd } /* Keyword.Reserved */ +.highlight .kt { color: #e5c07b } /* Keyword.Type */ +.highlight .ld { color: #98c379 } /* Literal.Date */ +.highlight .m { color: #d19a66 } /* Literal.Number */ +.highlight .s { color: #98c379 } /* Literal.String */ +.highlight .na { color: #d19a66 } /* Name.Attribute */ +.highlight .nb { color: #56b6c2 } /* Name.Builtin */ +.highlight .nc { color: #e5c07b } /* Name.Class */ +.highlight .no { color: #d19a66 } /* Name.Constant */ +.highlight .nd { color: #61afef } /* Name.Decorator */ +.highlight .ni { color: #abb2bf } /* Name.Entity */ +.highlight .ne { color: #e06c75 } /* Name.Exception */ +.highlight .nf { color: #61afef } /* Name.Function */ +.highlight .nl { color: #abb2bf } /* Name.Label */ +.highlight .nn { color: #e5c07b } /* Name.Namespace */ +.highlight .nx { color: #abb2bf } /* Name.Other */ +.highlight .py { color: #abb2bf } /* Name.Property */ +.highlight .nt { color: #e06c75 } /* Name.Tag */ +.highlight .nv { color: #e06c75 } /* Name.Variable */ +.highlight .ow { color: #c678dd } /* Operator.Word */ +.highlight .w { color: #abb2bf } /* Text.Whitespace */ +.highlight .mf { color: #d19a66 } /* Literal.Number.Float */ +.highlight .mh { color: #d19a66 } /* Literal.Number.Hex */ +.highlight .mi { color: #d19a66 } /* Literal.Number.Integer */ +.highlight .mo { color: #d19a66 } /* Literal.Number.Oct */ +.highlight .sb { color: #98c379 } /* Literal.String.Backtick */ +.highlight .sc { color: #98c379 } /* Literal.String.Char */ +.highlight .sd { color: #5c6370; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #98c379 } /* Literal.String.Double */ +.highlight .se { color: #56b6c2 } /* Literal.String.Escape */ +.highlight .sh { color: #98c379 } /* Literal.String.Heredoc */ +.highlight .si { color: #e5c07b } /* Literal.String.Interpol */ +.highlight .sx { color: #98c379 } /* Literal.String.Other */ +.highlight .sr { color: #56b6c2 } /* Literal.String.Regex */ +.highlight .s1 { color: #98c379 } /* Literal.String.Single */ +.highlight .ss { color: #56b6c2 } /* Literal.String.Symbol */ +.highlight .bp { color: #abb2bf } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #e06c75 } /* Name.Variable.Class */ +.highlight .vg { color: #e06c75 } /* Name.Variable.Global */ +.highlight .vi { color: #e06c75 } /* Name.Variable.Instance */ +.highlight .il { color: #d19a66 } /* Literal.Number.Integer.Long */ + +/* Copy block styles */ +.copy-btn { + position: absolute; + top: 8px; + right: 8px; + z-index: 2; + cursor: pointer; + padding: 6px 12px; + border-radius: 4px; + background-color: #3b4048; + color: #abb2bf; + border: 1px solid #181a1f; + font-size: 13px; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; + opacity: 0; + transition: opacity 0.2s, background-color 0.2s; +} -/* - Solarized Light - http://ethanschoonover.com/solarized +.copy-btn:hover { + background-color: #4b525b; + color: #ffffff; +} - SOLARIZED HEX ROLE - --------- -------- ------------------------------------------ - base01 #586e75 body text / default code / primary content - base1 #93a1a1 comments / secondary content - base3 #fdf6e3 background - orange #cb4b16 constants - red #dc322f regex, special keywords - blue #22b3eb reserved keywords - cyan #2aa198 strings, numbers - green #859900 operators, other keywords - ========================================================================== */ +div.highlighter-rouge:hover .copy-btn, figure.highlight:hover .copy-btn { + opacity: 1; +} -.highlight .c { color: #93a1a1 } /* Comment */ -.highlight .err { color: #586e75 } /* Error */ -.highlight .g { color: #586e75 } /* Generic */ -.highlight .k { color: #859900 } /* Keyword */ -.highlight .l { color: #586e75 } /* Literal */ -.highlight .n { color: #586e75 } /* Name */ -.highlight .o { color: #859900 } /* Operator */ -.highlight .x { color: #cb4b16 } /* Other */ -.highlight .p { color: #586e75 } /* Punctuation */ -.highlight .cm { color: #93a1a1 } /* Comment.Multiline */ -.highlight .cp { color: #859900 } /* Comment.Preproc */ -.highlight .c1 { color: #93a1a1 } /* Comment.Single */ -.highlight .cs { color: #859900 } /* Comment.Special */ -.highlight .gd { color: #2aa198 } /* Generic.Deleted */ -.highlight .ge { color: #586e75; font-style: italic } /* Generic.Emph */ -.highlight .gr { color: #dc322f } /* Generic.Error */ -.highlight .gh { color: #cb4b16 } /* Generic.Heading */ -.highlight .gi { color: #859900 } /* Generic.Inserted */ -.highlight .go { color: #586e75 } /* Generic.Output */ -.highlight .gp { color: #586e75 } /* Generic.Prompt */ -.highlight .gs { color: #586e75; font-weight: bold } /* Generic.Strong */ -.highlight .gu { color: #cb4b16 } /* Generic.Subheading */ -.highlight .gt { color: #586e75 } /* Generic.Traceback */ -.highlight .kc { color: #cb4b16 } /* Keyword.Constant */ -.highlight .kd { color: #22b3eb } /* Keyword.Declaration */ -.highlight .kn { color: #859900 } /* Keyword.Namespace */ -.highlight .kp { color: #859900 } /* Keyword.Pseudo */ -.highlight .kr { color: #22b3eb } /* Keyword.Reserved */ -.highlight .kt { color: #dc322f } /* Keyword.Type */ -.highlight .ld { color: #586e75 } /* Literal.Date */ -.highlight .m { color: #2aa198 } /* Literal.Number */ -.highlight .s { color: #2aa198 } /* Literal.String */ -.highlight .na { color: #586e75 } /* Name.Attribute */ -.highlight .nb { color: #B58900 } /* Name.Builtin */ -.highlight .nc { color: #22b3eb } /* Name.Class */ -.highlight .no { color: #cb4b16 } /* Name.Constant */ -.highlight .nd { color: #22b3eb } /* Name.Decorator */ -.highlight .ni { color: #cb4b16 } /* Name.Entity */ -.highlight .ne { color: #cb4b16 } /* Name.Exception */ -.highlight .nf { color: #22b3eb } /* Name.Function */ -.highlight .nl { color: #586e75 } /* Name.Label */ -.highlight .nn { color: #586e75 } /* Name.Namespace */ -.highlight .nx { color: #586e75 } /* Name.Other */ -.highlight .py { color: #586e75 } /* Name.Property */ -.highlight .nt { color: #22b3eb } /* Name.Tag */ -.highlight .nv { color: #22b3eb } /* Name.Variable */ -.highlight .ow { color: #859900 } /* Operator.Word */ -.highlight .w { color: #586e75 } /* Text.Whitespace */ -.highlight .mf { color: #2aa198 } /* Literal.Number.Float */ -.highlight .mh { color: #2aa198 } /* Literal.Number.Hex */ -.highlight .mi { color: #2aa198 } /* Literal.Number.Integer */ -.highlight .mo { color: #2aa198 } /* Literal.Number.Oct */ -.highlight .sb { color: #93a1a1 } /* Literal.String.Backtick */ -.highlight .sc { color: #2aa198 } /* Literal.String.Char */ -.highlight .sd { color: #586e75 } /* Literal.String.Doc */ -.highlight .s2 { color: #2aa198 } /* Literal.String.Double */ -.highlight .se { color: #cb4b16 } /* Literal.String.Escape */ -.highlight .sh { color: #586e75 } /* Literal.String.Heredoc */ -.highlight .si { color: #2aa198 } /* Literal.String.Interpol */ -.highlight .sx { color: #2aa198 } /* Literal.String.Other */ -.highlight .sr { color: #dc322f } /* Literal.String.Regex */ -.highlight .s1 { color: #2aa198 } /* Literal.String.Single */ -.highlight .ss { color: #2aa198 } /* Literal.String.Symbol */ -.highlight .bp { color: #22b3eb } /* Name.Builtin.Pseudo */ -.highlight .vc { color: #22b3eb } /* Name.Variable.Class */ -.highlight .vg { color: #22b3eb } /* Name.Variable.Global */ -.highlight .vi { color: #22b3eb } /* Name.Variable.Instance */ -.highlight .il { color: #2aa198 } /* Literal.Number.Integer.Long */ \ No newline at end of file +/* Fallback for touch devices */ +@media (hover: none) { + .copy-btn { + opacity: 1; + } +} \ No newline at end of file diff --git a/_sass/_variables.scss b/_sass/_variables.scss index c7ffff96e05..4ffc80cc9ef 100644 --- a/_sass/_variables.scss +++ b/_sass/_variables.scss @@ -6,7 +6,7 @@ Typography ========================================================================== */ -$doc-font-size : 14; +$doc-font-size : 15; /* paragraph indention */ $paragraph-indent : false; // true, false (default) @@ -14,11 +14,9 @@ $indent-var : 0.5em; /* system typefaces */ $serif : Georgia, Times, serif; -$sans-serif : "Trebuchet MS", Helvetica, sans-serif; -// $sans-serif : Georgia, serif, sans-serif; +$sans-serif : 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; -// $sans-serif : -apple-system, ".SFNSText-Regular", "San Francisco", "Roboto", "Segoe UI", "Helvetica Neue", "Lucida Grande", Arial, sans-serif; -$monospace : Monaco, Consolas, "Lucida Console", monospace; +$monospace : 'JetBrains Mono', Monaco, Consolas, "Lucida Console", monospace; /* sans serif typefaces */ $sans-serif-narrow : $sans-serif; @@ -36,39 +34,47 @@ $header-font-family : $sans-serif; $caption-font-family : $serif; /* type scale */ -$type-size-1 : 2.441em; // ~39.056px -$type-size-2 : 1.953em; // ~31.248px -$type-size-3 : 1.4em; // ~25.008px -$type-size-4 : 1.2em; // ~20px -$type-size-5 : 1em; // ~16px -$type-size-6 : 1em; // ~12px -$type-size-7 : 0.6875em; // ~11px -$type-size-8 : 0.625em; // ~10px +$type-size-1 : 2.5em; // ~40px - Hero +$type-size-2 : 2em; // ~32px - Section headers +$type-size-3 : 1.5em; // ~24px - Subsection +$type-size-4 : 1.25em; // ~20px - Card titles +$type-size-5 : 1em; // ~16px - Body +$type-size-6 : 0.9em; // ~14px - Small +$type-size-7 : 0.8em; // ~13px - Caption +$type-size-8 : 0.75em; // ~12px - Tiny /* - Colors + Colors - Modern Professional Palette ========================================================================== */ -$gray : #7a8288; -$dark-gray : mix(#000, $gray, 40%); -$darker-gray : mix(#000, $gray, 60%); -$light-gray : mix(#fff, $gray, 50%); -$lighter-gray : mix(#fff, $gray, 90%); +$gray : #64748b; +$dark-gray : #334155; +$darker-gray : #1e293b; +$light-gray : #94a3b8; +$lighter-gray : #f1f5f9; -$body-color : #fff; -$background-color : #fff; -$code-background-color : #fafafa; +$body-color : #ffffff; +$background-color : #ffffff; +$code-background-color : #f8fafc; $code-background-color-dark : $light-gray; -$text-color : $dark-gray; -$border-color : $lighter-gray; +$text-color : #334155; +$text-color-light : #64748b; +$border-color : #e2e8f0; -$primary-color : #7a8288; -$success-color : #62c462; -$warning-color : #f89406; -$danger-color : #ee5f5b; -$info-color : #224b8d; -// $info-color : #52adc8; +/* Primary accent - Professional Blue */ +$primary-color : #2563eb; +$primary-color-light : #3b82f6; +$primary-color-dark : #1d4ed8; + +$success-color : #10b981; +$warning-color : #f59e0b; +$danger-color : #ef4444; +$info-color : #2563eb; + +/* Gradient colors */ +$gradient-start : #2563eb; +$gradient-end : #7c3aed; /* brands */ $behance-color : #1769FF; @@ -80,13 +86,13 @@ $github-color : #171516; $google-plus-color : #dd4b39; $instagram-color : #517fa4; $lastfm-color : #d51007; -$linkedin-color : #007bb6; +$linkedin-color : #0077b5; $pinterest-color : #cb2027; $rss-color : #fa9b39; $soundcloud-color : #ff3300; $stackoverflow-color : #fe7a15; $tumblr-color : #32506d; -$twitter-color : #55acee; +$twitter-color : #1da1f2; $vimeo-color : #1ab7ea; $vine-color : #00bf8f; $youtube-color : #bb0000; @@ -94,11 +100,11 @@ $xing-color : #006567; /* links */ -$link-color : $info-color; -$link-color-hover : mix(#000, $link-color, 25%); -$link-color-visited : mix(#fff, $link-color, 25%); -$masthead-link-color : $primary-color; -$masthead-link-color-hover : mix(#000, $primary-color, 25%); +$link-color : $primary-color; +$link-color-hover : $primary-color-dark; +$link-color-visited : $primary-color; +$masthead-link-color : $dark-gray; +$masthead-link-color-hover : $primary-color; /* @@ -106,13 +112,6 @@ $masthead-link-color-hover : mix(#000, $primary-color, 25%); ========================================================================== */ @include breakpoint-set("to ems", true); -/* -$small : 400px; -$medium : 500px; -$medium-wide : 550px; -$large : 1200px; -$x-large : 1800px; -*/ $small : 600px !default; $medium : 768px !default; @@ -137,12 +136,6 @@ $susy: ( gutter-position: after, container: $large, global-box-sizing: border-box, - // debug: ( - // image: show, - // color: blue, - // output: overlay, - // toggle: top right, - // ), ); @@ -150,8 +143,11 @@ $susy: ( Other ========================================================================== */ -$border-radius : 4px; -$box-shadow : 0 1px 1px rgba(0, 0, 0, 0.125); +$border-radius : 8px; +$border-radius-lg : 12px; +$box-shadow : 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06); +$box-shadow-lg : 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); +$box-shadow-xl : 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); $navicon-width : 28px; $navicon-height : 4px; -$global-transition : all 0.2s ease-in-out; +$global-transition : all 0.3s cubic-bezier(0.4, 0, 0.2, 1); diff --git a/assets/css/main.scss b/assets/css/main.scss index b48c010bb4a..d99b46365f3 100644 --- a/assets/css/main.scss +++ b/assets/css/main.scss @@ -1,12 +1,15 @@ --- --- +/* ========================================================================== + Main stylesheet + ========================================================================== */ /* - * Minimal Mistakes Jekyll Theme + * Minimal Mistakes Jekyll Theme - Enhanced Edition * * - Michael Rose * - mademistakes.com - * - https://twitter.com/mmistakes + * - Enhanced by Abrar Eyasir * */ @@ -32,62 +35,122 @@ @import "page"; @import "archive"; +@import "posts"; @import "sidebar"; +@import "education"; + @import "vendor/font-awesome/fontawesome"; @import "vendor/font-awesome/solid"; @import "vendor/font-awesome/brands"; @import "vendor/magnific-popup/magnific-popup"; @import "print"; +/* ========================================================================== + ENHANCED PAPER/PROJECT BOXES + ========================================================================== */ + .paper-box { display: flex; - justify-content: left; - align-items: center; - flex-direction: row; - flex-wrap: wrap; - border-bottom: 1px #efefef solid; - padding: 2em 0 2em 0; + justify-content: flex-start; + align-items: flex-start; + flex-direction: column; + border: none; + border-radius: $border-radius-lg; + padding: 1.5em 1.75em; + margin: 1.5em 0; + background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05); + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); + position: relative; + overflow: visible; + border: 1px solid rgba(0, 0, 0, 0.04); + border-left: 4px solid $primary-color; - - .paper-box-image{ - justify-content: center; - display: flex; - width: 100%; - order: 2; - img { - max-width: 400px; - box-shadow: 3px 3px 6px #888; - object-fit: cover; - } + &:hover { + transform: translateX(6px); + box-shadow: 0 8px 30px rgba(37, 99, 235, 0.1); + border-color: rgba(37, 99, 235, 0.08); + border-left-color: $primary-color; } - - .paper-box-text{ - max-width: 100%; - order: 1; + + .paper-box-image { + display: none; } - @include breakpoint($medium) { - .paper-box-image{ - justify-content: left; - min-width: 200px; - max-width: 40%; - order: 1; + .paper-box-text { + width: 100%; + + strong { + font-size: 1.1em; + color: $darker-gray; + line-height: 1.4; + display: block; + margin-bottom: 0.2em; + padding-right: 0; } - .paper-box-text{ - justify-content: left; - padding-left: 2em; - max-width: 60%; - order: 2; + em { + color: $gray; + font-size: 0.88em; + display: block; + margin-bottom: 0.6em; + } + + a { + color: $primary-color; + font-weight: 500; + + &:hover { + color: $primary-color-dark; + } + } + + ul { + margin-top: 0.6em; + margin-bottom: 0; + padding-left: 1.2em; + + li { + margin-bottom: 0.4em; + line-height: 1.55; + color: $text-color; + font-size: 0.92em; + + &:last-child { + margin-bottom: 0; + } + + strong { + display: inline; + font-size: 1em; + } + } } - } +} - +.badge { + display: inline-block; + padding: 0.35em 0.9em; + color: white; + background: linear-gradient(135deg, $primary-color 0%, #7c3aed 100%); + font-size: 0.78em; + font-weight: 600; + border-radius: 50px; + letter-spacing: 0.02em; + box-shadow: 0 2px 10px rgba(37, 99, 235, 0.3); + position: absolute; + top: 1em; + right: 1em; + margin-bottom: 0; } -$scroll_offset : 2em; +/* ========================================================================== + SCROLL OFFSET FOR ANCHORS + ========================================================================== */ + +$scroll_offset: 2em; h1:before, .anchor:before { content: ''; display: block; @@ -97,13 +160,436 @@ h1:before, .anchor:before { margin-top: -$scroll_offset; } -.badge { - padding-left: 1rem; - padding-right: 1rem; - position: absolute; - margin-top: .5em; - margin-left: -.5em; - color: white; - background-color: #00369f; - font-size: .8em; +/* ========================================================================== + ENHANCED NEWS SECTION + ========================================================================== */ + +.page__content ul { + li { + position: relative; + padding-left: 0; + + &::marker { + color: $primary-color; + } + } +} + +/* News items styling */ +.page__content > ul > li { + padding: 0.3em 0; + border-radius: $border-radius; + transition: all 0.2s ease; +} + +/* ========================================================================== + SKILL TAGS & BADGES + ========================================================================== */ + +.skill-tag { + display: inline-block; + padding: 0.35em 0.8em; + margin: 0.25em; + background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%); + color: $dark-gray; + border-radius: 50px; + font-size: 0.85em; + font-weight: 500; + transition: all 0.3s ease; + border: 1px solid transparent; + + &:hover { + background: linear-gradient(135deg, $primary-color 0%, $primary-color-light 100%); + color: white; + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(37, 99, 235, 0.25); + } +} + +.skill-category { + margin-bottom: 1.5em; + + strong { + display: block; + margin-bottom: 0.5em; + color: $darker-gray; + font-size: 0.95em; + } +} + +/* ========================================================================== + EXPERIENCE TIMELINE + ========================================================================== */ + +.experience-item { + position: relative; + padding: 30px 32px; + margin: 0 0 26px; + background: #ffffff; + border-radius: $border-radius-lg; + border: 1px solid #eee; + border-left: 3px solid $primary-color; + box-shadow: 0 10px 30px rgba(15, 23, 42, 0.04); + transition: transform 0.22s ease, box-shadow 0.22s ease, border-color 0.22s ease; + + &:hover { + transform: translateY(-2px); + box-shadow: 0 14px 40px rgba(15, 23, 42, 0.06); + border-color: #e9e9e9; + } + + .experience-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + flex-wrap: wrap; + margin-bottom: 14px; + gap: 12px; + } + + .experience-title { + font-weight: 750; + color: $darker-gray; + font-size: 1.25em; + margin-bottom: 0.2em; + letter-spacing: -0.01em; + } + + .experience-company { + color: #334155; /* elegant dark grey */ + font-weight: 650; + font-size: 1.0em; + } + + .experience-meta { + text-align: right; + display: flex; + flex-direction: column; + align-items: flex-end; + gap: 6px; + min-width: 180px; + } + + .experience-date { + color: $primary-color; + background: transparent; + border: 1px solid rgba(37, 99, 235, 0.35); + padding: 0.28em 0.75em; + border-radius: 999px; + font-size: 0.8em; + font-weight: 650; + letter-spacing: 0.02em; + white-space: nowrap; + box-shadow: none; + } + + .experience-supervisor { + color: $gray; + font-size: 0.85em; + font-style: normal; + margin-top: 0; + line-height: 1.2; + } + + ul { + margin: 0; + padding-left: 0; + list-style: none; + + li { + position: relative; + margin-bottom: 0.65em; + padding-left: 1.1em; + line-height: 1.6; + color: $text-color; + font-size: 0.96em; + + &:last-child { + margin-bottom: 0; + } + + &::before { + content: "–"; + position: absolute; + left: 0; + top: 0; + color: rgba(100, 116, 139, 0.75); /* subtle slate */ + font-weight: 500; + } + + strong { + color: $darker-gray; + font-weight: 650; + } + } + } +} + +/* ========================================================================== + AWARDS SECTION + ========================================================================== */ + +.award-item { + display: flex; + align-items: center; + padding: 0.8em 0; + border-bottom: 1px solid $border-color; + transition: all 0.2s ease; + + &:last-child { + border-bottom: none; + } + + &:hover { + background: #f8fafc; + padding-left: 0.5em; + border-radius: $border-radius; + } + + .award-year { + min-width: 60px; + font-weight: 700; + color: $primary-color; + } + + .award-icon { + margin-right: 0.8em; + font-size: 1.2em; + } + + .award-title { + flex: 1; + } +} + +/* ========================================================================== + CONTACT SECTION + ========================================================================== */ + +.contact-section { + background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); + border-radius: $border-radius-lg; + padding: 2em; + margin-top: 2em; + text-align: center; + + .contact-links { + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 1em; + margin-top: 1em; + + a { + display: inline-flex; + align-items: center; + gap: 0.5em; + padding: 0.8em 1.5em; + background: white; + border: 2px solid $border-color; + border-radius: 50px; + color: $dark-gray; + font-weight: 500; + text-decoration: none; + transition: all 0.3s ease; + + &:hover { + border-color: $primary-color; + color: $primary-color; + transform: translateY(-2px); + box-shadow: 0 4px 15px rgba(37, 99, 235, 0.15); + } + + i { + font-size: 1.2em; + } + } + } +} + +/* ========================================================================== + SECTION HEADERS + ========================================================================== */ + +.page__content h1 { + position: relative; + display: inline-block; + margin-top: 2em; + margin-bottom: 1em; + padding-bottom: 0.5em; + font-weight: 700; + color: $darker-gray; + + &::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + width: 60px; + height: 4px; + background: linear-gradient(90deg, $primary-color, #7c3aed); + border-radius: 2px; + } +} + +/* ========================================================================== + LINK BUTTONS + ========================================================================== */ + +.btn-link { + display: inline-flex; + align-items: center; + gap: 0.5em; + padding: 0.6em 1.2em; + margin: 0.3em 0.5em 0.3em 0; + background: linear-gradient(135deg, $primary-color 0%, $primary-color-light 100%); + color: white !important; + border-radius: 50px; + font-size: 0.85em; + font-weight: 600; + text-decoration: none !important; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + border: none; + + &:hover { + transform: translateY(-3px); + box-shadow: 0 6px 20px rgba(37, 99, 235, 0.4); + background: linear-gradient(135deg, $primary-color-dark 0%, $primary-color 100%); + } + + i { + font-size: 1.1em; + } +} + +.btn-link-outline { + display: inline-flex; + align-items: center; + gap: 0.5em; + padding: 0.55em 1.2em; + margin: 0.3em 0.5em 0.3em 0; + background: white; + color: $primary-color !important; + border: 2px solid $primary-color; + border-radius: 50px; + font-size: 0.85em; + font-weight: 600; + text-decoration: none !important; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + + &:hover { + background: $primary-color; + color: white !important; + transform: translateY(-3px); + box-shadow: 0 6px 20px rgba(37, 99, 235, 0.3); + } + + i { + font-size: 1.1em; + } +} + +/* ========================================================================== + RESPONSIVE IMPROVEMENTS + ========================================================================== */ + +@media (max-width: 600px) { + .paper-box { + padding: 1.25em; + margin: 1.25em 0; + + .paper-box-text { + strong { + font-size: 1.1em; + } + } + } + + .experience-item { + padding: 1.25em; + + .experience-header { + flex-direction: column; + gap: 0.5em; + } + + .experience-date { + align-self: flex-start; + } + } + + .contact-section .contact-links { + flex-direction: column; + align-items: center; + } + + .btn-link, .btn-link-outline { + padding: 0.5em 1em; + font-size: 0.8em; + } +} + +/* ========================================================================== + CODE BLOCKS ENHANCEMENT + ========================================================================== */ + +code { + padding: 0.2em 0.5em; + background: #f1f5f9; + border-radius: 4px; + font-size: 0.9em; + color: #d63384; +} + +pre { + background: #1e293b; + color: #e2e8f0; + padding: 1.5em; + border-radius: $border-radius; + overflow-x: auto; + + code { + background: transparent; + color: inherit; + padding: 0; + } +} + +/* ========================================================================== + SELECTION STYLING + ========================================================================== */ + +::selection { + background: rgba(37, 99, 235, 0.2); + color: $darker-gray; +} + +::-moz-selection { + background: rgba(37, 99, 235, 0.2); + color: $darker-gray; +} + +/* ========================================================================== + FOCUS STATES FOR ACCESSIBILITY + ========================================================================== */ + +a:focus, +button:focus { + outline: 2px solid $primary-color; + outline-offset: 2px; +} + +/* ========================================================================== + PRINT OPTIMIZATION + ========================================================================== */ + +@media print { + .masthead, + .sidebar { + display: none; + } + + .page { + width: 100%; + } } \ No newline at end of file diff --git a/images/Abrar.png b/images/Abrar.png new file mode 100644 index 00000000000..874b7cecec4 Binary files /dev/null and b/images/Abrar.png differ diff --git a/images/abrar-eyasir.png b/images/abrar-eyasir.png new file mode 100644 index 00000000000..0845bcabcc7 Binary files /dev/null and b/images/abrar-eyasir.png differ diff --git a/images/android-chrome-192x192.png b/images/android-chrome-192x192.png old mode 100755 new mode 100644 index 5e8d9034999..5e7149ec5b5 Binary files a/images/android-chrome-192x192.png and b/images/android-chrome-192x192.png differ diff --git a/images/android-chrome-512x512.png b/images/android-chrome-512x512.png old mode 100755 new mode 100644 index d34eb21c439..eb10c398c45 Binary files a/images/android-chrome-512x512.png and b/images/android-chrome-512x512.png differ diff --git a/images/apple-touch-icon.png b/images/apple-touch-icon.png old mode 100755 new mode 100644 index 9de4c24bdd3..586fa975bf4 Binary files a/images/apple-touch-icon.png and b/images/apple-touch-icon.png differ diff --git a/images/favicon-16x16.png b/images/favicon-16x16.png old mode 100755 new mode 100644 index 59307a0cede..7ae06fbecea Binary files a/images/favicon-16x16.png and b/images/favicon-16x16.png differ diff --git a/images/favicon.ico b/images/favicon.ico old mode 100755 new mode 100644 index 83aa24b99f2..a0cbbd76f87 Binary files a/images/favicon.ico and b/images/favicon.ico differ